【问题标题】:EXC_BAD_ACCESS on NSManagedObjectContext save method inside NSOperation and ARC, why?NSOperation 和 ARC 中 NSManagedObjectContext 保存方法上的 EXC_BAD_ACCESS,为什么?
【发布时间】: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


【解决方案1】:

也许 ARC 释放了一些接收 NSManagedObjectContextDidSaveNotification 的对象,这会导致异常? 我有类似的东西,并通过确保在对象被释放之前 removeObserver: 来修复它。

请注意,CoreData 异常实际上隐藏了通知中心异常,因此您看不到它。

【讨论】:

  • 谢谢Yonat!是的,你完全正确。我刚刚尝试删除Observer: - 它没有帮助。
  • 我在共享上下文的单身人士的dealloc 中调用了removeObserver:。删除dealloc 解决了问题,但我应该去哪里removeObserver
  • 同时检查你是否多次调用 addObserver。经验法则是在 viewDidLoad 上执行,然后在 dealloc 上调用 removeObserver。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-20
  • 1970-01-01
相关资源
最近更新 更多