gpt4 book ai didi

objective-c - insertNewObjectForEntityForName 上的 exc_bad_access :inManagedObjectContext

转载 作者:行者123 更新时间:2023-12-03 16:44:53 30 4
gpt4 key购买 nike

我为我遇到的问题编写了一个最小的代码示例。我通过两种方式实现后台工作:手动生成线程和让 NSOperation 处理线程。在这两种情况下,我都为每个线程/操作创建NSManagedObjectContexts

当我自己使用performSelectorInBackground:withObject:生成线程时,一切正常。当我切换到将对象传递给 NSOperationQueue 时,我在尝试保存操作 NSManagedObjectContext 时看到以下错误。

-EXC_BAD_ACCESS - Serious application error. Exception was caught during Core Data change processing: *** -[NSCFSet addObject:]: attempt to insert nil with userInfo (null) - _referenceData64 only defined for abstract class. Define -[NSTemporaryObjectID_default _referenceData64]!

我相信该错误(尤其是最后一个错误)与使用临时 objectID 在线程/上下文之间传递对象有关。可能,更糟糕的是,我以某种方式在线程之间传递 NSManagedObjects

无论哪种方式,我都找不到任何表明我这样做的代码。

我的最小代码示例可以找到 here .

大部分工作是在 awakeFromNib 中的 AppDelegate 中完成的。将 EXECUTE_WITH_NSOPERATION 设置为 0 以使用 performSelectorInBackground:withObject: 运行。将 EXECUTE_WITH_NSOPERATION 保留为 1,以使用 NSOperationQueue 执行,这将创建一堆 MCBoardParse 对象。

我只在 10.6 下看到这个。

原版

我有一个基于 10.5 框架构建的 Cocoa 应用程序。在 NSOperation 中,在一个循环中,我快速创建了数百个 NSManagedObjects。通常,这些 NSManagedObejcts 的创建会因 EXC_BAD_ACCESS 错误而崩溃。这种情况在引用计数内存管理和垃圾收集下都会发生。

    for (offsetCount; offsetCount < [parsedData count]; offsetCount++) {
NSManagedObject *child = [NSEntityDescription insertNewObjectForEntityForName:@"Thread" inManagedObjectContext:[self moc]];
Thumbnail *thumb = [Thumbnail insertInManagedObjectContext:[self moc]];
Image *image = [Image insertInManagedObjectContext:[self moc]];
...
}

Thumbnail 和 Image 都是使用 mogenerator 生成的 NSManagedObject 的子类。 insertInManagedObjectContext:看起来像

    NSParameterAssert(moc_);
return [NSEntityDescription insertNewObjectForEntityForName:@"Thumbnail" inManagedObjectContext:moc_];

NSParameterAssert(moc_);
return [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:moc_];
The NSManagedObjectContext returned by [self moc] is created for the NSOperation with

NSPersistentStoreCoordinator *coord = [(MyApp_AppDelegate *)[[NSApplication sharedApplication] delegate] persistentStoreCoordinator];
self.moc = [[NSManagedObjectContext alloc] init];
[self.moc setPersistentStoreCoordinator:coord];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.moc];
[self.moc setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[self.moc setUndoManager:nil];
[self.moc setRetainsRegisteredObjects:YES];

moc 被定义为(nonatomic,retain) 并被合成。据我所知,持久存储和我的 appDelegate 没有理由也没有被垃圾收集。

堆栈跟踪看起来像

Thread 2 Crashed:  Dispatch queue: com.apple.root.default-priority
0 libauto.dylib 0x00007fff82d63600 auto_zone_root_write_barrier + 688
1 libobjc.A.dylib 0x00007fff826f963b objc_assign_strongCast_gc + 59
2 com.apple.CoreFoundation 0x00007fff88677068 __CFBasicHashAddValue + 504
3 com.apple.CoreFoundation 0x00007fff88676d2f CFBasicHashAddValue + 191
4 com.apple.CoreData 0x00007fff82bdee5e -[NSManagedObjectContext(_NSInternalAdditions) _insertObjectWithGlobalID:globalID:] + 190
5 com.apple.CoreData 0x00007fff82bded24 -[NSManagedObjectContext insertObject:] + 148
6 com.apple.CoreData 0x00007fff82bbd75c -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] + 716
7 com.apple.CoreData 0x00007fff82bdf075 +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] + 101
8 com.yourcompany.MyApp 0x000000010002c7a7 +[_Thumbnail insertInManagedObjectContext:] + 256 (_Thumbnail.m:14)
9 com.yourcompany.MyApp 0x000000010002672d -[ThreadParse main] + 10345 (ThreadParse.m:174)
10 com.apple.Foundation 0x00007fff85ee807e -[__NSOperationInternal start] + 698
11 com.apple.Foundation 0x00007fff85ee7d23 ____startOperations_block_invoke_2 + 99
12 libSystem.B.dylib 0x00007fff812bece8 _dispatch_call_block_and_release + 15
13 libSystem.B.dylib 0x00007fff8129d279 _dispatch_worker_thread2 + 231
14 libSystem.B.dylib 0x00007fff8129cbb8 _pthread_wqthread + 353
15 libSystem.B.dylib 0x00007fff8129ca55 start_wqthread + 13

我的应用程序在其他地方因 EXC_BAD_ACCESS 崩溃,但这是最常发生这种情况的代码。所有堆栈跟踪看起来都很相似,并且与 CFHash 有关。

最佳答案

如果您因 exc_bad_access 而崩溃,则意味着您过度释放了对象,或者在释放对象后调用了该对象的方法。这两种情况都很糟糕,与 Core Data 无关。您正在使用垃圾收集的事实可能是一个线索,表明某些内容正在取消引用,因此在您期望之前就进行了垃圾收集。

第一个问题是,您是否为每个 NSOperation 实例创建一个新的 NSManagedObjectContext

其次,我建议打开 NSZombie (我相信你现在可以通过工具来完成),这将有助于缩小释放后调用对象的代码的范围,等等。进行 Google 搜索NSZombie 和 Instruments 上会出现几篇操作方法文章。

更新

由于这是 10.6 的问题,因此它可能与 NSOperation 实例而不是 Core Data 实例有关。您的操作是否标记为并发?我问的原因是 NSOperation 忽略 10.6 上的并发标志,这可能会导致一些令人讨厌的意外。

更新2

在我审查整个问题时请注意。该行:

self.moc = [[NSManagedObjectContext alloc] init];

如果没有释放,将会泄漏内存(至少在 GC 关闭时),因为 alloc init 会增加保留计数,然后 [self setMoc:] 调用也会增加保留计数。

关于objective-c - insertNewObjectForEntityForName 上的 exc_bad_access :inManagedObjectContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2475449/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com