8

我无法让支持核心数据的 NSArrayController 在我的代码中正常工作。下面是我的代码:

pageArrayController = [[NSArrayController alloc] initWithContent:nil];
    [pageArrayController setManagedObjectContext:[self managedObjectContext]];
    [pageArrayController setEntityName:@"Page"];
    [pageArrayController setAvoidsEmptySelection:YES];
    [pageArrayController setPreservesSelection:YES];
    [pageArrayController setSelectsInsertedObjects:YES];
    [pageArrayController setClearsFilterPredicateOnInsertion:YES];
    [pageArrayController setEditable:YES];
    [pageArrayController setAutomaticallyPreparesContent:YES];
    [pageArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]]];
    BOOL result = [pageArrayController setSelectionIndex:0];

当我尝试调用 setSelectionIndex: 时,它返回 YES,表示选择已成功更改。但是,任何后续对 pageArrayController 对象的 getSelectionIndex 调用都会返回 NSNotFound。

我不明白的是,如果我将 NSArrayController 放入 NIB,并允许 NIB 文件执行初始化(在 Interface Builder 中具有所有相同的属性),则 NSArrayController 可以正常工作。

为什么行为上有差异?NIB 文件是否以特殊方式初始化这些类型的对象?我对 NSArrayController 的初始化不正确吗?

任何帮助表示赞赏。谢谢。

4

3 回答 3

16

是的,nib 确实以一种特殊的方式初始化对象,有时很难弄清楚如何复制它。我也为此苦苦挣扎,最后在 Apple 的 Core Data Programming Guide >> Core Data and Cooca Bindings >> Automatically Prepares Content Flag中找到了答案(感谢Cocoa Dev列表中的 Dave Fernandes)。答案是,如果您使用 nil 内容初始化 arraycontroller,您还需要执行 fetch。

BOOL result;
NSArrayController *pageArrayController = [[NSArrayController alloc] initWithContent:nil];
[pageArrayController setManagedObjectContext:[self managedObjectContext]];
[pageArrayController setEntityName:@"Page"];
NSError *error;
if ([pageArrayController fetchWithRequest:nil merge:YES error:&error] == NO) 
     result = NO;
else
{
     //do all that other pageArrayController configuration stuff
     result = [pageArrayController setSelectionIndex:0];
}

顺便说一句,[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]] 引发警告。

于 2009-12-07T20:25:35.887 回答
0

至于为什么行为可能会有所不同:

  1. Nib 文件使用 NSCoder 存储序列化对象。
  2. 您可能在 IB 方面使用绑定,在您的代码中,您正在使用 set 方法直接设置托管对象上下文。

也许您可以在代码中尝试类似以下的内容:

[pageArrayController bind:@"managedObjectContext"
                 toObject:self
              withKeyPath:@"managedObjectContext"
                  options:nil];

我附近没有 Xcode,否则我会尝试一些东西。希望这能给你一些线索,让你朝着正确的方向前进。

于 2009-12-07T16:13:00.137 回答
0

您从哪里创建/配置阵列控制器?核心数据堆栈可能还没有准备好,因此您对 [self managedObjectContext] 的调用可能会返回 nil。

另外,如果您可以使用 Interface Builder 很好地创建它,为什么还要以编程方式创建它?该工具在那里并且运行良好(并且消除了许多可能的编码错误),因此除非您有充分的理由不使用它,否则您不会给自己带来任何好处。

于 2009-12-07T20:24:07.067 回答