3

详细信息在评论中。

以下代码:

// 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);

结果如下:

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)'

任何想法将不胜感激。仅供参考,如果我使用不同的模板作为起点,上面的代码可以在单独的应用程序中完美运行。即如果我使用“基于窗口的应用程序”模板,代码将失败。如果我使用“基于导航的应用程序”,代码将按预期工作。

更新: TechZen 想知道问题是否是由我的提醒实体引起的。我认为这是一个好主意,所以我做了以下事情:

  1. 创建两个默认模板应用程序:一个“基于窗口的应用程序”和一个“基于导航的应用程序”(都启用了 Core Data)

  2. 将执行上述测试所需的最少代码从基于导航复制到基于窗口(几乎只是“xcdatamodel”文件、fetchedresultscontroller 和添加测试对象的方法)。

上面的代码在新的“无提醒实体”的基于窗口的应用程序中仍然失败。(在这个新的测试应用程序中,实际上我自己编写的代码为零(在测试代码之外),它只是模板代码剪切和粘贴在一起。)

所以现在,我正在寻找在创建“基于窗口的应用程序”之后运行上述代码的任何方法。这是使用基于导航的默认实体执行测试的代码,以防有人有兴趣尝试一下:

更新请注意,正如 TechZen 在下面指出的那样,无论使用空数据库运行此代码都会崩溃,因此如果从基于窗口的应用程序开始,首先向数据库添加一些对象,然后添加测试代码。

// 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这里是使用新的剪切粘贴代码时的输出

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)'

更新所以我将这个问题缩小为与 SDK 版本相关的问题,我现在有一个项目,如果我使用 Simulator 3.2 构建它会崩溃,而使用 Simulator 3.1.3 构建它可以正常工作。但是如果我添加一个 UITableViewController,然后使用 Simulator 3.2 构建,那么它又可以正常工作了。所以我创建了一个新的 stackoverflow帖子来问这个问题:如果你使用 NSFetchedResultsController 没有 UITableViewController,你如何与对象交互?(因为 IndexPaths 不可靠)。

更新这个问题(暂时)通过使用 -[NSFetchedResultsController fetchedObjects] objectAtIndex:]来访问对象来解决。

4

6 回答 6

3

这可以通过使用 -[NSFetchedResultsController fetchedObjects] objectAtIndex:] 来绕过

于 2010-07-22T23:13:41.907 回答
3

您是否尝试过NSFetchedResultsController在仅内存跟踪模式下使用?(仅内存跟踪:delegate 为非 nil 且文件缓存名称设置为 nil)

于 2012-03-01T17:43:48.727 回答
2

我想我会愚蠢地指出 NSLog(@"%@",indexPath) 将始终返回 null?

你需要做

NSLog(@"section %i",(int)indexPath.section);
NSLog(@"row %i",(int)indexPath.row);

不是吗?

于 2010-11-25T13:25:44.723 回答
1

查看 fetchedResultsController 的 sortDescriptors 顺序。Section key 字段必须先 sortDescriptor 才能按顺序排列。

如果 fetchedResultsController 有多个 sortDescriptor 并且第一个描述符不是 indexPathForObject 的节键字段:方法无法解析 indexPath。

于 2013-03-24T15:23:20.230 回答
0

What does the creation of the NSFetchedResultsController look like?

Update

FYI, you can update your question with the code instead of using PasteBin.

Are you using multiple threads in this code anywhere to access the NSFetchedResultsController?

于 2010-07-17T16:53:07.740 回答
0

我将您的代码复制并粘贴到默认的核心数据导航模板中,将实体更改为带有字符串属性的提醒,textContent它运行良好。此代码或获取结果控制器的设置没有任何问题。

我认为问题实际上出在您的Reminder实体、Reminder类或textContent属性或对象上。这些错误可能是由于无法正确处理提醒对象造成的。


编辑:

确保仅在将某些对象添加到上下文后才运行此测试。如果没有对象,它将崩溃。我将使用基于窗口的模板进行测试。

于 2010-07-18T15:28:08.737 回答