我正在从服务器下载内容并将其保存在使用 CoreData 框架管理的 SQLite 数据库中。它有效,但我偶尔会发生我不明白的崩溃。这是我的崩溃报告:
Thread 5 name: Dispatch queue: com.apple.root.default-priority
Thread 5 Crashed:
0 libobjc.A.dylib 0x38eca5b6 objc_msgSend + 22
1 CoreData 0x30fe354c getValueCore + 24
2 CoreData 0x30fe34fa _PFCMT_GetValue + 6
3 CoreData 0x30fe346a -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] + 34
4 CoreData 0x30fe6ece -[_NSFaultingMutableSet willRead] + 394
5 CoreData 0x30fe7518 -[_NSFaultingMutableSet member:] + 84
6 CoreFoundation 0x3119aa50 -[NSSet countForObject:] + 16
7 CoreFoundation 0x3123a9f4 -[NSSet isSubsetOfSet:] + 516
8 Foundation 0x31b2a902 NSKeyValueWillChangeBySetMutation + 406
9 Foundation 0x31ac2c48 NSKeyValueWillChange + 404
10 Foundation 0x31b2a760 -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:withSetMutation:usingObjects:] + 260
11 CoreData 0x3101e71c -[NSManagedObject willChangeValueForKey:withSetMutation:usingObjects:] + 80
12 CoreData 0x31022f26 -[NSManagedObject(_NSInternalMethods) _excludeObject:fromPropertyWithKey:andIndex:] + 626
13 CoreData 0x31023df4 -[NSManagedObject(_NSInternalMethods) _maintainInverseRelationship:forProperty:oldDestination:newDestination:] + 228
14 CoreData 0x31024622 -[NSManagedObject(_NSInternalMethods) _didChangeValue:forRelationship:named:withInverse:] + 1286
15 CoreData 0x3102dc3e -[NSManagedObjectContext observeValueForKeyPath:ofObject:change:context:] + 318
16 Foundation 0x31ac36b4 NSKeyValueNotifyObserver + 268
17 Foundation 0x31ac330e NSKeyValueDidChange + 330
18 Foundation 0x31a9d6ce -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 90
19 CoreData 0x3101e234 _PF_ManagedObject_DidChangeValueForKeyIndex + 100
20 CoreData 0x310287b2 _sharedIMPL_setvfk_core + 222
21 Instabay 0x000bf3a0 -[AdGetMemberStuffsWSProxy processData:] (AdGetMemberStuffsWSProxy.m:101)
22 Instabay 0x000a7328 -[IBAbstractWSProxy didReceiveData:] (IBAbstractWSProxy.m:437)
23 CoreFoundation 0x312389c0 __invoking___ + 64
24 CoreFoundation 0x3118ffe6 -[NSInvocation invoke] + 282
25 Foundation 0x31b38b60 -[NSInvocationOperation main] + 108
26 Foundation 0x31ac25bc -[__NSOperationInternal start] + 836
27 Foundation 0x31b3abde __block_global_6 + 98
28 libdispatch.dylib 0x392e711c _dispatch_call_block_and_release + 8
29 libdispatch.dylib 0x392f5254 _dispatch_root_queue_drain + 256
30 libdispatch.dylib 0x392f53b4 _dispatch_worker_thread2 + 80
31 libsystem_c.dylib 0x3931ba0e _pthread_wqthread + 358
32 libsystem_c.dylib 0x3931b8a0 start_wqthread + 4
还有发生崩溃的方法:
- (id) processData:(id)theData
{
NSManagedObjectContext *moc = self.backgroundMOC;
// Fetch Members
NSDictionary *existingMembersMap = [[IBWSUtils fetchExistingMembersListBy:@"memberId"
inManagedObjectContext:moc]
retain];
// Fetch existing Ads (we only need the Id to build our cache mapping)
NSDictionary *existingAdsMap = [[IBWSUtils fetchExistingAdsListInManagedObjectContext:moc] retain];
IBMember *member = (IBMember *)[moc objectWithID:self.memberObjectID];
// Purge existing results, otherwise leave as is and simply append to the bottom
if (! self.shouldAppendResults)
{
if (member.stuffs != nil) {
[member removeStuffs:member.stuffs];
}
// member.stuffs = nil;
}
// Sets total number of ads
member.stuffsCount = [NSNumber numberWithInteger:[theData integerForKey:@"quantity"]];
NSArray *ads = [theData objectForKey:@"ad"];
for (NSDictionary *adDict in ads)
{
if ([adDict isKindOfClass:[NSNull class]]) {
continue;
}
// @autoreleasepool
{
NSString *currentAdId = [adDict objectForKey:@"id"];
// Get existing ad copy
IBAd *currentAd = [existingAdsMap objectForKey:currentAdId];
if (!currentAd)
{
// Otherwise, create a new ad instance
currentAd = [NSEntityDescription insertNewObjectForEntityForName:@"Ad"
inManagedObjectContext:moc];
currentAd.adId = currentAdId;
currentAd.creationDate = [NSDate dateWithTimeIntervalSince1970:[[adDict nonNullValueForKeyPath:@"createdAt.sec"] floatValue]];
}
currentAd.adDescription = [adDict objectForKey:@"description"];
// If member instance doesn't exist, create a new one
NSString *memberId = [adDict nonNullValueForKeyPath:@"seller.memberId"];
IBMember *existingMember = [existingMembersMap objectForKey:memberId];
if (!existingMember)
{
existingMember = [NSEntityDescription insertNewObjectForEntityForName:@"Member"
inManagedObjectContext:moc];
existingMember.memberId = memberId;
existingMember.userName = [adDict nonNullValueForKeyPath:@"seller.memberName"];
}
**// The line below is the line 101 that causes the crash
currentAd.member = existingMember;**
@try {
currentAd.mediaURI = [[[adDict objectForKey:@"media"] objectAtIndex:0] objectForKey:@"uri"];
}
@catch (NSException *exception) {
currentAd.mediaURI = nil;
}
IBWanted *wants = currentAd.wants;
if (!wants)
{
// Otherwise, create a new ad instance
wants = [NSEntityDescription insertNewObjectForEntityForName:@"Wanted"
inManagedObjectContext:moc];
currentAd.wants = wants;
}
wants.count = [NSNumber numberWithInteger:[adDict integerForKey:@"followWanted"]];
[member addStuffsObject:currentAd];
}
}
// Save operation
[self saveBackgroundManagedObjectContext];
[existingAdsMap release];
[existingMembersMap release];
return nil;
}
我不知道我做错了什么。
** 编辑 ** 此错误仅发生在设备上。模拟器没问题。