私が抱えている問題の最小限のコード例を書きました。バックグラウンド作業を 2 つの方法で実装しました。スレッドを手動で生成する方法と、スレッドNSOperation
処理を処理する方法です。どちらの場合もNSManagedObjectContexts
、スレッド/操作ごとに作成しています。
自分でスレッドを生成すると、performSelectorInBackground:withObject:
すべて正常に動作します。オブジェクトを に渡すように切り替えるとNSOperationQueue
、操作を保存しようとすると、次のエラーが表示されますNSManagedObjectContext
。
-EXC_BAD_ACCESS - 重大なアプリケーション エラーです。Core Data 変更処理中に例外がキャッチされました: *** -[NSCFSet addObject:]: userInfo (null) で nil を挿入しようとしています - _referenceData64 は抽象クラスに対してのみ定義されています。-[NSTemporaryObjectID_default_referenceData64] を定義してください!
特に最後のエラーを考えると、バグは、スレッド/コンテキスト間でオブジェクトを渡すために一時的な objectID を使用することに関係していると思います。さらに悪いことに、私はどういうわけかNSManagedObjects
スレッド間を行き来しています。
いずれにせよ、そうしていることを示唆するコードが見つかりません。
私の最小限のコード例はここにあります。
ほとんどの作業は で行われAppDelegate
ますawakeFromNib
。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 はどちらもNSManagedObject
mogenerator で生成されたサブクラスです。 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
.