コアデータのWebサービスからダウンロードされたJSONデータを保持するバックグラウンドスレッドがあります。これは、奇妙で不安定な場合を除いて、期待通りに機能します。私はこれがなぜ起こるのかを特定することができず、再現できない。これは、シミュレータとデバイスの両方で発生しているため、メモリ関連ではありません。バックグラウンドスレッドで奇数コアデータがクラッシュする
クラッシュする方法は次のとおりです。
+ (Hotspot *)insertOrUpdateWithDictionary:(NSDictionary *)hotspotJSON error:(NSError **)error {
NSManagedObjectContext *moc = [[ContentProviderController sharedContentProviderController] managedObjectContext];
Hotspot *hotspot = [Hotspot managedObjectWithPrimaryKey:[hotspotJSON objectForKey:@"id"] error:error];
if (*error == nil) {
if (hotspot) {
// Delete hotspot and cascade to other managed objects
[moc deleteObject:hotspot];
}
hotspot = [NSEntityDescription insertNewObjectForEntityForName:@"Hotspot" inManagedObjectContext:moc];
[hotspot setJSONProperties:hotspotJSON error:error];
}
if (*error == nil) {
return hotspot;
}
return nil;
}
managedObjectWithPrimaryKeyは次のようになります。
+ (Hotspot *)managedObjectWithPrimaryKey:(NSString *)primaryKey error:(NSError **)error {
if (primaryKey) {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:[[ContentProviderController sharedContentProviderController] managedObjectContext] ]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(hotspotId like %@)", primaryKey];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchLimit:1];
NSArray *results = [[[ContentProviderController sharedContentProviderController] managedObjectContext] executeFetchRequest:fetchRequest error:error];
RELEASE_SAFELY(fetchRequest);
if (*error == nil && results) {
return ([results count] > 0) ? [results objectAtIndex:0] : nil;
} else {
GTMLoggerError(@"error while retrieving process with hotspotId=%@; %@", primaryKey, [*error description]);
return nil;
}
} else {
*error = [NSError errorWithDomain:kCoreDataPersistenceError code:1000 userInfo:[NSDictionary dictionaryWithObject:@"Attempt to access an Hotspot with an invalid (null) hotspotId." forKey:NSLocalizedDescriptionKey]];
return nil;
}
}
setJSONProperties単に以下のように管理対象オブジェクトのプロパティを設定しています。次のように
- (void)setJSONProperties:(NSDictionary *)dictionary error:(NSError **)error {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//ここでホットスポットのプロパティを設定
RELEASE_SAFELY(pool);
}
クラッシュログが見えます。
** Call stack at first throw:
(
0 CoreFoundation 0x36b5964f __exceptionPreprocess + 114
1 libobjc.A.dylib 0x33db2c5d objc_exception_throw + 24
2 CoreFoundation 0x36b58edf __NSFastEnumerationMutationHandler + 214
3 libobjc.A.dylib 0x33db936d objc_enumerationMutation + 24
4 CoreData 0x36ee5c89 -[NSManagedObjectContext executeFetchRequest:error:] + 1888
5 magazine 0x000cd76d +[Page managedObjectWithPrimaryKey:error:] + 288
6 magazine 0x000ccc65 -[Hotspot setJSONProperties:error:] + 724
7 magazine 0x000cc943 +[Hotspot insertOrUpdateWithDictionary:error:] + 194
8 magazine 0x000c3d39 -[ContentProviderController persistHotspots:] + 368
9 magazine 0x000c05e5 -[ContentProviderController doPersistenceJobForIssueObjectId:] + 704
10 CoreFoundation 0x36b5c7a4 __invoking___ + 68
11 CoreFoundation 0x36ad443d -[NSInvocation invoke] + 108
12 Foundation 0x34f8043f -[NSInvocationOperation main] + 78
13 Foundation 0x34f19d1b -[__NSOperationInternal start] + 658
14 Foundation 0x34f19a7f -[NSOperation start] + 22
15 Foundation 0x34f7fecb ____startOperations_block_invoke_2 + 46
16 libdispatch.dylib 0x339d88e7 _dispatch_call_block_and_release + 10
17 libdispatch.dylib 0x339d362d _dispatch_worker_thread2 + 252
18 libsystem_c.dylib 0x3483c591 _pthread_wqthread + 264
19 libsystem_c.dylib 0x3483cbc4 _init_cpu_capabilities + 4294967295
)
私は完全に列挙しながら、オブジェクトが変異してはならないことを理解しますが、別の管理対象オブジェクト(ページ)が(このスレッドで見ている理由私は理解していないことである - [ホットスポットsetJSONProperties:エラー:] + 724)。各管理対象オブジェクトは順番に保持されるため、この「ホットスポット」オブジェクトの前に「ページ」オブジェクトが永続化されていました。