为什么可能在 - [_ PFManagedObjectReferenceQueue _queueForDealloc:]中释放托管对象? [英] Why might releasing a managed object crash in -[_PFManagedObjectReferenceQueue _queueForDealloc:]?
问题描述
我偶尔会看到这样的堆栈跟踪崩溃:
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
不幸的是,它是随机的再现。有谁有任何想法,可能会导致这样的崩溃?不帮助没有人似乎在互联网上提到过 -_ queueForDealloc:
!
对过去类似问题的模糊记忆,这是在仍然有KVO观察者附加时释放被管理对象的症状。任何人都同意?
最终能够在开发机器上重现问题,似乎这种崩溃是一个副作用
-
MOC
正在解除分配,因此现在是解除其内容的时间 - 为此,所有注册的
MOs
转为故障* - 将
MO
KVO通知 - 观察者收到通知并尝试对其进行操作,并在图表中触及无效的
MO
- 核心数据从无效访问中抛出异常
- 由于未知原因,该异常不会传递给我的异常报告
-
MO
被释放,但是异常使Core Data处于意外状态,因此MO
释放崩溃
简单来说,真正的问题是观察者比上下文更长;不允许他们!任何观察到 MO
的对象都应该强烈引用 MOC
,例如 NSObjectController
和朋友做。
*我发现在测试Core Data经常在后台线程上这样做,主线程
MOC
- 受管对象上下文
MO
- 受管对象
I am occasionally seeing crashes with a stack trace like this:
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
Unfortunately, it's rather random to reproduce. Does anyone have any ideas what could cause such a crash? Doesn't help that no-one seems to have mentioned -_queueForDealloc:
on the internet before!
I have a vague memory of a similar problem in the past where this was a symptom of deallocating a managed object while it still had KVO observers attached. Anyone concur?
Having finally been able to reproduce the problem on a development machine, it seems this crash is a side-effect of an earlier exception during context teardown.
The sequence of events is something like:
- The
MOC
is being deallocated, so it's time to tear down its contents - To do so, all registered
MOs
are turned into faults* - The act of turning a
MO
into a fault sends KVO-notifications - An observer receives the notification and tries to act upon it, hitting a now invalid
MO
in the graph - Core Data throws an exception from the invalid access
- For reasons unknown, that exception is not passed to my exception reporter
- The
MO
s get released, but the exception left Core Data in an unexpected state, so theMO
deallocation crashes
In short the real problem is that observers outlive the context; don't allow them to! Any object observing a MO
should probably also have a strong reference to the MOC
, like NSObjectController
and friends do.
*I found in testing that Core Data often does this on a background thread, presumably to avoid blocking the main thread
MOC
– managed object context
MO
– managed object
这篇关于为什么可能在 - [_ PFManagedObjectReferenceQueue _queueForDealloc:]中释放托管对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!