NSFetchedResultsController返回带有null indexPaths的对象 [英] NSFetchedResultsController returning objects with null indexPaths
问题描述
详细信息在注释中。
以下代码:
//执行fetch ...
NSError * error = nil;
if(![[self fetchedResultsController] performFetch:& error]){
NSLog(@未解析的错误%@,%@,错误,[错误userInfo]);
abort();
}
//确认对象是通过计数取得的
NSLog(@Number of Objects =%i,
[[fetchedResultsController fetchedObjects ] count]);
//通过计数来确认节存在...
NSLog(@Numbers of Sections =%i,
[[fetchedResultsController sections] count]);
([fetchedResultsController sections]中的id部分){
//计算每个节中对象的数量
// _这个输出0的事实是trouble_的第一个符号
NSLog(@Section in Objects =%i,[section numberOfObjects]);
}
([fetchedResultsController fetchedObjects]中的提醒*提醒){
//通过访问它们来确认获取的对象实际上是真实对象
// textContentproperty ...
NSLog(@textContent =%@,reminder.textContent);
//显示正在返回获取的对象
//带有(null)indexPath ...
// _麻烦的第二个标志... _
NSLog(@IndexPath =%@,
[fetchedResultsController indexPathForObject:reminder]);
}
NSUInteger indexArr [] = {0,0};
NSIndexPath * indexPath = [NSIndexPath indexPathWithIndexes:indexArr
length:2];
// _Application在此行上崩溃,因为获取的
//对象没有indexPaths_
提醒* testReminder =(Reminder *)[fetchedResultsController
objectAtIndexPath:indexPath ];
NSLog(@textContent =%@,testReminder.textContent);
得到以下输出结果:
2010-07-17 00:48:41.865提醒[27335:207]对象数= 3
/ pre>
2010-07-17 00:48:41.867提醒[27335:207]节数= 1
2010-07-17 00:48:41.868提醒[27335:207]节中的对象数= 0
2010-07-17 00:48:41.870提醒[27335: 207] textContent =导入对象3
2010-07-17 00:48:41.871提醒[27335:207] IndexPath =(null)
2010-07-17 00:48:41.873提醒[27335: 207] textContent = Imported Object 2
2010-07-17 00:48:41.873提醒[27335:207] IndexPath =(null)
2010-07-17 00:48:41.874提醒[27335: 207] textContent =导入对象1
2010-07-17 00:48:41.875提醒[27335:207] IndexPath =(null)
2010-07-17 00:48:41.887提醒[27335: 207] ***由于未捕获异常NSRangeException终止应用程序,原因:'*** - [NSCFArray objectAtIndex:]:index(0)超出边界(0)'
任何想法都将非常感谢。如果我使用不同的模板作为起点,上面的代码在一个单独的应用程序完美地工作。也就是说如果我使用基于窗口的应用程序模板,代码将失败。如果我使用基于导航的应用程序代码工作正常。
更新: TechZen想知道是否是由我的提醒实体。我认为这是一个好主意,所以我做了以下:
创建两个默认模板应用程序:基于窗口的应用程序和基于导航的应用程序(都启用了核心数据)。
基于窗口执行上面的测试(几乎只是xcdatamodel文件,fetchedresultscontroller和一种添加测试对象的方法)。
上述代码在新的Reminder-entity free基于窗口的应用程序中仍然失败。 (在这个新的测试应用程序中,实际上是我自己创建的零代码(在测试代码之外),所有的都是模板代码剪切和粘贴在一起。)
现在,我正在寻找任何方式,以获得上述代码在创建基于Window的应用程序后运行。下面是使用基于导航的默认实体执行测试的代码,以防任何人试图尝试:
UPDATE 注意,由于下面的注释,这个代码将崩溃,无论如果运行一个空数据库,所以如果从一个基于窗口的应用程序,首先添加一些对象到数据库,然后添加测试代码。
//确认提取的对象
NSLog(@Number of Objects =%i,
[[fetchedResultsController fetchedObjects]计数]);
//确认节存在
NSLog(@Numbers of Sections =%i,
[[fetchedResultsController sections] count]);
([fetchedResultsController sections]中的id部分){
//计算节中对象的数量
// _输出0的事实是第一个sign of trouble_
NSLog(@Section of Objects in Section =%i,[section numberOfObjects]);
}
([fetchedResultsController fetchedObjects]中的NSManagedObject * managedObject){
//确认获取的对象实际上是真实对象
//通过访问他们的timeStamp属性
NSLog(@TimeStamp =%@,[[managedObject valueForKey:@timeStamp] description]);
//显示正在返回获取的对象
//带有(null)indexPath
// _麻烦的第二个标志..._
NSLog (@IndexPath =%@,
[fetchedResultsController indexPathForObject:managedObject]);
}
NSUInteger indexArr [] = {0,0};
NSIndexPath * indexPath = [NSIndexPath indexPathWithIndexes:indexArr
length:2];
// _Application在此行上崩溃,因为获取的
//对象没有indexPaths_
NSManagedObject * managedObject = [fetchedResultsController
objectAtIndexPath:indexPath];
NSLog(@textContent =%@,[[managedObject valueForKey:@timeStamp] description]);
UPDATE 这里是使用新的剪切和粘贴代码
2010-07-18 15:33:41.264提醒[30898:207]对象数= 3
2010-07-18 15:33:41.266提醒[30898:207]节数= 1
2010-07-18 15:33:41.267提醒[30898:207]节中的对象数= 0
2010-07-18 15:33:41.270提醒[30898:207] TimeStamp = 2010-07-18 13:59:00 -0400
2010-07-18 15:33:41.271提醒[30898: 207] IndexPath =(null)
2010-07-18 15:33:41.272提醒[30898:207] TimeStamp = 2010-07-18 13:59:00 -0400
2010-07-18 15:33:41.273提醒[30898:207] IndexPath =(null)
2010-07-18 15:33:41.274提醒[30898:207] TimeStamp = 2010-07-18 13:58:59 -0400
2010-07-18 15:33:41.275提醒[30898:207] IndexPath =(null)
2010-07-18 15:33:41.276提醒[30898:207] ***终止应用程序由于未捕获异常NSRangeException,原因:'*** - [NSCFArray objectAtIndex:]:index(0)超出边界(0)'
UPDATE 所以我把这个问题缩小到一个SDK版本相关的问题,我现在有一个项目,如果我用Simulator 3.2构建它崩溃,与模拟器3.1.3它工作正常。但如果我添加一个UITableViewController,然后构建与Simulator 3.2,那么它再次工作正常。因此,我创建了一个新的stackoverflow 帖子来提出问题:如果您使用NSFetchedResultsController没有UITableViewController,你如何与对象进行交互? (因为IndexPath不可靠)。
UPDATE 此问题(暂时)通过使用 -
[NSFetchedResultsController fetchedObjects ] objectAtIndex:]
以访问对象。解决方案可以通过使用 - [NSFetchedResultsController fetchedObjects] objectAtIndex:]
Details are in the comments.
The following code:
// Perform the fetch... NSError *error = nil; if (![[self fetchedResultsController] performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } // Confirm that objects were fetched by counting them... NSLog(@"Number of Objects = %i", [[fetchedResultsController fetchedObjects] count]); // Confirm that sections exist by counting them... NSLog(@"Numbers of Sections = %i", [[fetchedResultsController sections] count]); for (id section in [fetchedResultsController sections]) { // Count number of objects in each section // _The fact that this outputs 0 is the first sign of trouble_ NSLog(@"Number of Objects in Section = %i", [section numberOfObjects]); } for (Reminder *reminder in [fetchedResultsController fetchedObjects]) { // Confirm that the objects fetched are in fact real objects // by accessing their "textContent" property... NSLog(@"textContent=%@", reminder.textContent); // Show that the fetched objects are being returned // with a (null) indexPath... // _The second sign of trouble..._ NSLog(@"IndexPath=%@", [fetchedResultsController indexPathForObject:reminder]); } NSUInteger indexArr[] = {0,0}; NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexArr length:2]; // _Application crashes on this line because the fetched // objects do not have indexPaths_ Reminder *testReminder = (Reminder *)[fetchedResultsController objectAtIndexPath:indexPath]; NSLog(@"textContent = %@", testReminder.textContent);
Results in the following output:
2010-07-17 00:48:41.865 Reminders[27335:207] Number of Objects = 3 2010-07-17 00:48:41.867 Reminders[27335:207] Numbers of Sections = 1 2010-07-17 00:48:41.868 Reminders[27335:207] Number of Objects in Section = 0 2010-07-17 00:48:41.870 Reminders[27335:207] textContent=Imported Object 3 2010-07-17 00:48:41.871 Reminders[27335:207] IndexPath=(null) 2010-07-17 00:48:41.873 Reminders[27335:207] textContent=Imported Object 2 2010-07-17 00:48:41.873 Reminders[27335:207] IndexPath=(null) 2010-07-17 00:48:41.874 Reminders[27335:207] textContent=Imported Object 1 2010-07-17 00:48:41.875 Reminders[27335:207] IndexPath=(null) 2010-07-17 00:48:41.887 Reminders[27335:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
Any ideas would be greatly appreciated. FYI, the above code works perfectly in a separate application if I use a different template as a starting point. I.e. if I use the "Window-based application" template, the code will fail. If I use "Navigation-based application" the code works as expected.
Update: TechZen was wondering if the problem is caused by my Reminder entity. I thought this was a good idea to look into, so I did the following:
Create two default template applications: a "Window-based application" and a "Navigation-based Application" (both with Core Data enabled)
Copied over the minimum code needed from the Nav-based to the Window-based to perform the above test (pretty much just the "xcdatamodel" file, the fetchedresultscontroller, and a way to add test objects).
The above code still fails in the new "Reminder-entity free" window-based application. (In this new test application there is in fact zero code I've authored myself (outside of the test code), it's all just template code cut-and-pasted together.)
So now, I am looking for any way to get the above code to run after creating a "Window-based application". Here is the code to perform the test using the nav-based's default entity, in case anyone is interested in giving it a try:
UPDATE Note that as TechZen noted below this code will crash no matter what if run with an empty database, so if starting from a window-based application, first add a few objects to the database then add the test code.
// Confirm that objects were fetched NSLog(@"Number of Objects = %i", [[fetchedResultsController fetchedObjects] count]); // Confirm that sections exist NSLog(@"Numbers of Sections = %i", [[fetchedResultsController sections] count]); for (id section in [fetchedResultsController sections]) { // Count number of objects in sections // _The fact that this outputs 0 is the first sign of trouble_ NSLog(@"Number of Objects in Section = %i", [section numberOfObjects]); } for (NSManagedObject *managedObject in [fetchedResultsController fetchedObjects]) { // Confirm that the objects fetched are in fact real objects, // by accessing their "timeStamp" property NSLog(@"TimeStamp=%@", [[managedObject valueForKey:@"timeStamp"] description]); // Show that the fetched objects are being returned // with a (null) indexPath // _The second sign of trouble..._ NSLog(@"IndexPath=%@", [fetchedResultsController indexPathForObject:managedObject]); } NSUInteger indexArr[] = {0,0}; NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexArr length:2]; // _Application crashes on this line, because the fetched // objects do not have indexPaths_ NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath]; NSLog(@"textContent = %@", [[managedObject valueForKey:@"timeStamp"] description]);
UPDATE here is the output when using the new cut-and-pasted code
2010-07-18 15:33:41.264 Reminders[30898:207] Number of Objects = 3 2010-07-18 15:33:41.266 Reminders[30898:207] Numbers of Sections = 1 2010-07-18 15:33:41.267 Reminders[30898:207] Number of Objects in Section = 0 2010-07-18 15:33:41.270 Reminders[30898:207] TimeStamp=2010-07-18 13:59:00 -0400 2010-07-18 15:33:41.271 Reminders[30898:207] IndexPath=(null) 2010-07-18 15:33:41.272 Reminders[30898:207] TimeStamp=2010-07-18 13:59:00 -0400 2010-07-18 15:33:41.273 Reminders[30898:207] IndexPath=(null) 2010-07-18 15:33:41.274 Reminders[30898:207] TimeStamp=2010-07-18 13:58:59 -0400 2010-07-18 15:33:41.275 Reminders[30898:207] IndexPath=(null) 2010-07-18 15:33:41.276 Reminders[30898:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
UPDATE So I narrowed this problem down to being an SDK version-related issue, I now have a project that if I build with Simulator 3.2 it crashes, and build with Simulator 3.1.3 it works fine. BUT if I add a UITableViewController, then build with Simulator 3.2, then it works fine again. So I've created a new stackoverflow post to ask the question: If you are using NSFetchedResultsController without a UITableViewController, how do you interact with the objects? (since the IndexPaths are unreliable).
UPDATE This issue is (tentatively) solved by using -
[NSFetchedResultsController fetchedObjects] objectAtIndex:]
to access the objects.解决方案This can be bypassed by using -[NSFetchedResultsController fetchedObjects] objectAtIndex:]
这篇关于NSFetchedResultsController返回带有null indexPaths的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!