Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 为什么在-[[u PFManagedObjectReferenceQueue]中释放托管对象会崩溃?_Cocoa_Core Data_Nsmanagedobject - Fatal编程技术网

Cocoa 为什么在-[[u PFManagedObjectReferenceQueue]中释放托管对象会崩溃?

Cocoa 为什么在-[[u PFManagedObjectReferenceQueue]中释放托管对象会崩溃?,cocoa,core-data,nsmanagedobject,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 0x9

我偶尔会看到堆栈跟踪崩溃,如下所示:

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
不幸的是,这是相当随机复制。有人知道是什么导致了这样的事故吗?没有人以前在互联网上提到过
-\u queueForDealloc:
,这也没用


我对过去的一个类似问题记忆犹新,在这个问题中,这是在托管对象仍然连接有KVO观察器的情况下取消分配托管对象的症状。有人同意吗?

-\u queueForDealloc:
是一种未记录的内部方法。它不时出现在堆栈中,但我们无法直接处理它

您的问题很可能是由于过度释放managedObject造成的。managedObject将由插入、更新或更改对象的上下文强烈保留,因此如果您对对象本身的保留进行微观管理,则可以在上下文释放它之前过度释放它。这会导致托管对象看似随机地消失。相反,您可以过度保留,导致对象在上下文删除后保持不变


我鼓励人们避免保留托管对象,但当您保留托管对象时,请将它们放在类属性或集合(如数组或集合)中。这样,就可以为您处理保留

终于能够在开发机器上重现这个问题,看来这次崩溃是上下文分解过程中早期异常的副作用

事件的顺序类似于:

  • MOC
    正在被解除分配,因此是时候拆除它的内容了
  • 为此,所有注册的
    MOs
    都会变成故障*
  • MO
    转换为故障的行为会发送KVO通知
  • 观察者收到通知并尝试对其采取行动,在图中点击现在无效的
    MO
  • 核心数据从无效访问引发异常
  • 由于未知原因,该异常未传递给我的异常报告程序
  • MO
    s被释放,但异常使核心数据处于意外状态,因此
    MO
    解除分配崩溃
  • 简而言之,真正的问题是观察家比环境更长寿;别让他们这么做!任何观察到
    MO
    的对象可能也会强烈引用
    MOC
    ,就像
    NSObjectController
    和朋友一样

    *我在测试中发现,核心数据通常在后台线程上执行此操作,可能是为了避免阻塞主线程

    MOC
    –托管对象上下文

    MO
    –托管对象

    我有另一个解决方案,所以要解决这个bug。在示例中,ARC的MOC属性类似于(只读、强、非原子)

    经过数周的关于时间崩溃的讨论,我找到了osx的解决方案(只需删除非原子元素)


    现在它完美了,所有的崩溃都消失了。

    当在
    NSOperation
    中使用私有托管对象上下文时,我们遇到了一个类似的问题,我们最终通过修改任何参数和使用私有
    @autoreleasepool
    解决了这个问题。我将在下面进一步阐述

    我们当前的设置有一个
    NSOperationQueue
    ,它有一个我们在后台进行的长时间运行的计算。该操作首先创建一个私有的托管对象上下文,将父对象集作为主对象上下文,然后去获取它的对象

    同时,我们在其他地方有一个单独的
    NSOperationQueue
    ,用于同步服务器上的新数据,可能会添加、更新或删除计算操作使用的对象

    我们首先在野外看到了一系列这样的崩溃,在本地重新编程的唯一方法是让计算和同步操作连续运行,5-10分钟后,我们会看到类似于以下之一的崩溃:

    Thread : Crashed: background queue :: NSOperation 0x18f43c90
    0  libobjc.A.dylib                0x36f11f46 objc_msgSend + 5
    1  CoreData                       0x2928408f -[NSManagedObject release] + 166
    2  CoreData                       0x2927b4d7 -[_PFArray dealloc] + 94
    3  libobjc.A.dylib                0x36f201a9 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 404
    4  CoreFoundation                 0x294713a9 _CFAutoreleasePoolPop + 16
    5  Foundation                     0x2a1b6453 -[__NSOperationInternal _start:] + 1058
    6  Foundation                     0x2a25b44b __NSOQSchedule_f + 186
    7  libdispatch.dylib              0x3746d651 _dispatch_queue_drain + 952
    8  libdispatch.dylib              0x3746809d _dispatch_queue_invoke + 84
    9  libdispatch.dylib              0x3746eba1 _dispatch_root_queue_drain + 320
    10 libdispatch.dylib              0x3746fcd7 _dispatch_worker_thread3 + 94
    11 libsystem_pthread.dylib        0x375c6e31 _pthread_wqthread + 668
    
    
    Thread : Crashed: background queue :: NSOperation 0x1db59e80
    0  libsystem_kernel.dylib         0x3722edfc __pthread_kill + 8
    1  libsystem_pthread.dylib        0x372acd37 pthread_kill + 62
    2  libsystem_c.dylib              0x371ce909 abort + 76
    3  libsystem_malloc.dylib         0x37258331 szone_size
    4  libobjc.A.dylib                0x36bf1621 object_dispose + 20
    5  CoreData                       0x28ec571d -[_PFManagedObjectReferenceQueue dealloc] + 80
    6  CoreData                       0x28e5630f -[NSManagedObject dealloc] + 166
    7  CoreData                       0x28e55217 -[_PFManagedObjectReferenceQueue _queueForDealloc:] + 246
    8  CoreData                       0x28e5508f -[NSManagedObject release] + 166
    9  CoreData                       0x28e4c4d7 -[_PFArray dealloc] + 94
    10 libobjc.A.dylib                0x36c031a9 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 404
    11 CoreFoundation                 0x29042149 _CFAutoreleasePoolPop + 16
    12 Foundation                     0x29d88c23 -[__NSOperationInternal _start:] + 1058
    13 Foundation                     0x29e2dc1b __NSOQSchedule_f + 186
    14 libdispatch.dylib              0x371505b1 _dispatch_queue_drain + 952
    15 libdispatch.dylib              0x3714af85 _dispatch_queue_invoke + 84
    16 libdispatch.dylib              0x37151b9b _dispatch_root_queue_drain + 338
    17 libdispatch.dylib              0x37152cd7 _dispatch_worker_thread3 + 94
    18 libsystem_pthread.dylib        0x372a9e31 _pthread_wqthread + 668
    
    
    Thread : Crashed: NSOperationQueue Serial Queue
    0  libsystem_kernel.dylib         0x396871f0 __pthread_kill + 8
    1  libsystem_pthread.dylib        0x396ef7b7 pthread_kill + 58
    2  libsystem_c.dylib              0x39637ff9 abort + 76
    3  libsystem_malloc.dylib         0x396aed25 szone_size
    4  libobjc.A.dylib                0x390d93a9 object_dispose + 20
    5  CoreData                       0x2e3d4081 -[_PFManagedObjectReferenceQueue dealloc] + 80
    6  CoreData                       0x2e3655b7 -[NSManagedObject dealloc] + 166
    7  CoreData                       0x2e364501 -[_PFManagedObjectReferenceQueue _queueForDealloc:] + 244
    8  CoreData                       0x2e36437d -[NSManagedObject release] + 164
    9  CoreData                       0x2e35b867 -[_PFArray dealloc] + 94
    10 libobjc.A.dylib                0x390e20d3 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
    11 CoreFoundation                 0x2e5294c1 _CFAutoreleasePoolPop + 16
    12 Foundation                     0x2ef29999 -[__NSOperationInternal _start:] + 1064
    13 Foundation                     0x2efcd745 __NSOQSchedule_f + 60
    14 libdispatch.dylib              0x395c0cbd _dispatch_queue_drain + 488
    15 libdispatch.dylib              0x395bdc6f _dispatch_queue_invoke + 42
    16 libdispatch.dylib              0x395c15f1 _dispatch_root_queue_drain + 76
    17 libdispatch.dylib              0x395c18dd _dispatch_worker_thread2 + 56
    18 libsystem_pthread.dylib        0x396ecc17 _pthread_wqthread + 298
    
    我们多次查看代码,无法确定它崩溃的原因。我们尝试启用NSZombies,但在重新启动之前,内存就会耗尽

    我们最终做了以下两件事:

    @autoreleasepool

    在我们的
    [privateObjectContext performBlockAndWait:^{…}]
    中,我们将所有代码包装在
    @autoreleasepool{…}
    中。这样,在该代码块期间检索到的所有NSManagedObject都将在离开performBlockAndWait之前标记为释放

    weakify/strongify


    包含NSManagedObjects的任何参数在传递到块之前都会被禁用,在块中会被禁用一次。这样,因为我们不再有对它们的强引用,所以当我们等待
    NSOperation
    启动时,如果它们变得过时,就可以释放它们。这里有一篇关于weakify/strongify如何工作的好文章:

    那么你是说我过度发布了这个对象?显然,从堆栈跟踪来看,
    -release
    正在被调用,因此决定是时候释放对象了(我假设核心数据在达到像Cocoa的其余部分一样的保留计数为零时会这样做)。但是,作为解除分配例程的一部分,核心数据解除分配对象,然后向其发送消息?这根本没有道理!我不认为我看到的是你的常规内存管理错误,我认为上下文仍然引用了一个managedObject,该对象由于过度扩展而在先前的耗尽中被杀死。上下文仍然认为对象是活动的,并将对它的引用放入队列中。然后它尝试发送各种删除和释放方法,但对象不再位于内存地址。由于“取消管理”managedObject并将其从对象图中删除是一个复杂的过程,具有许多副作用,因此不正确地删除对象会导致崩溃,具体取决于gra的特定状态