为什么可能会释放托管对象 - [_ PFManagedObjectReferenceQueue _queueForDealloc:]?

Mik*_*lah 8 cocoa core-data nsmanagedobject

我偶尔会看到像这样的堆栈跟踪崩溃:

0 libobjc.A.dylib 0x97dc0edb objc_msgSend + 27
1 com.apple.CoreData 0x97edcdc2 -[_PFManagedObjectReferenceQueue _queueForDealloc:] + 162
2 com.apple.CoreData 0x97edccbe -[NSManagedObject release] + 94
3 com.apple.CoreFoundation 0x9318ef38 CFRelease + 152
4 com.apple.CoreFoundation 0x931a7460 __CFBasicHashStandardCallback + 384
5 com.apple.CoreFoundation 0x931a706e __CFBasicHashDrain + 478
6 com.apple.CoreFoundation 0x9318f101 _CFRelease + 353
7 com.apple.CoreFoundation 0x931bbc6d _CFAutoreleasePoolPop + 253
8 com.apple.Foundation 0x973270aa NSPopAutoreleasePool + 76
9 com.apple.Foundation 0x97326fd2 -[NSAutoreleasePool drain] + 130
10 com.apple.AppKit 0x95087185 -[NSApplication run] + 627
11 com.apple.AppKit 0x9507f2d9 NSApplicationMain + 574
12 com.karelia.Sandvox 0x70001ef6 start + 54
Run Code Online (Sandbox Code Playgroud)

不幸的是,重现它是相当随机的.有没有人有什么想法会导致这样的崩溃?没有人-_queueForDealloc:在互联网上似乎没有提到过没有帮助!

我对过去类似的问题有一个模糊的记忆,这是一个释放托管对象的症状,同时它还附加了KVO观察者.有人同意吗?

Mik*_*lah 11

最终能够在开发机器上重现问题,看起来这次崩溃是上下文拆除时早期异常的副作用.

事件的顺序如下:

  1. MOC被释放,所以现在是时候推倒的内容
  2. 为此,所有注册的MOs人都会变成故障*
  3. 将a MO变为故障的行为发送KVO通知
  4. 观察者收到通知并尝试对其进行操作,MO在图表中点击现在无效
  5. Core Data会从无效访问中引发异常
  6. 由于未知原因,该异常未传递给我的异常报告者
  7. MO小号得到释放,但例外意外状态留核心数据,所以MO释放崩溃

简而言之,真正的问题是观察者比上下文更长久; 不要让他们!观察一个物体的任何物体MO都应该有一个强烈的参考MOC,像NSObjectController和朋友一样.

*我在测试中发现Core Data经常在后台线程上执行此操作,可能是为了避免阻塞主线程

MOC- 托管对象上下文
MO- 托管对象