【发布时间】:2012-02-23 18:33:09
【问题描述】:
在打开 ARC 的情况下将 NSManagedObjectContext 保存在 NSOperation 中时,我发现了一些问题。没有ARC之前一切都很好。保存期间总是给出 EXC_BAD_ACCESS。代码如下所示:
//on the main thread
-(void)someFunc
{
array = ... //fetching an array of entities from a core data
for(SomeEntity * obj in array)
{
NSSomeOperation * op = [[NSSomeOperation alloc] initWithValue:[obj someField]];
//start an operation
}
}
//NSSomeOperation implementation
//...
- (void)main {
//some code
NSError * error = nil;
[mainContext lock];
if (![mainContext save:&error]) { //<--- HERE EXC_BAD_ACCESS
//process error
}
[mainContext unlock];
//some code
}
//...
使用 [mainContext setRetainsRegisteredObjects:YES] 和 objectWithID 不能解决此问题。
EXC_BAD_ACCESS(代码=1)
EXC_BAD_ACCESS(代码=13)
-[__NSCFType contextDidSave:]: unrecognized selector sent to instance 0x7fc5c505d940
An observer of NSManagedObjectContextDidSaveNotification illegally threw an exception.
Objects saved = {
inserted = "{(\n)}";
updated = "{(\n <SomeEntity: 0x7fc5c55b6220> (entity: SomeEntity; id: 0x7fc5c5052b20 ... )}"; }
and exception = -[__NSCFType contextDidSave:]: unrecognized selector sent to instance 0x7fc5c505d940 with userInfo = (null)
我使用单独的托管对象上下文并在此 NSOperation 中获取我的托管对象。
也许这与 Core Data 错误或 ARC 相关?也许ARC清理了一些必须保存的对象? 因为,没有 ARC,一切都很好,一切正常。当我打开 ARC - EXC_BAD_ACCESS。
有人知道为什么会这样吗?
【问题讨论】:
-
不,吉姆。这是在 NSOperation 内部,在另一个线程上。
-
好吧,我问的原因是因为你可以添加一个 NSOperation 到主队列(使用 NSOperationQueue mainQueue] addOperation:...]。如果这是在辅助线程或队列上,你在关注吗? Apple 文档使用单独的托管对象上下文,并将您的更改合并回主队列中的上下文?
-
NSOperationQueue 在主线程上,是的。是的,我在 NSOperation 中创建了第二个 NSManagedObjectContext,但是在 init 方法中。并将更改与主 NSManagedObjectContext(在主线程上创建)上的 performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) 合并。也许我需要在 NSOperation 的“main”方法中创建 NSManagedObjectContext 对象(第二个)?
-
看起来一切都是对的,如果它在主线程上的话。如果您已经在主线程上,则不需要 performSelectorOnMainThread,但这无关紧要。此外,如果它在主线程上,则使用 init 或 main 也没关系。 (对于必须在辅助线程上的工作,您应该使用 start 方法,但这与您描述的情况无关。)
-
如果您可以发布您的项目,我会看看它,看看我是否可以提出任何建议。
标签: objective-c multithreading core-data exc-bad-access automatic-ref-counting