0
我有一個後臺線程持久從核心數據中的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)。每個託管對象都是按順序保存的,因此在此「熱點」對象之前,「頁面」對象將被保留。