2011-08-06 61 views
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)。每個託管對象都是按順序保存的,因此在此「熱點」對象之前,「頁面」對象將被保留。

回答

0

好吧,事實證明,罪魁禍首是一個非常複雜的事件組合,它們產生了兩個同時發生的Core Data線程,試圖對相同的數據進行更改。

停止解決了這個問題。