當我使用NSPersistentStoreUbiquitousContentNameKey
和NSPersistentStoreUbiquitousContentURLKey
添加持久性存儲時,我的應用程序每隔兩次崩潰但出現異常。這發生在調用addPersistentStoreWithType:configuration:URL:options:error:
當使用Core Data和iCloud添加持久性存儲時涉及PFUbiquityPeer的例外
堆棧跟蹤看起來是這樣的過程:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: 'An NSManagedObject of class 'PFUbiquityPeer' must have a valid
NSEntityDescription.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff8b35ffc6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff83368d5e objc_exception_throw + 43
2 CoreData 0x00007fff82c28c06 -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] + 182
3 CoreData 0x00007fff82d4d3dc +[PFUbiquityPeer(UbiquityMethods) peerForPeerID:inManagedObjectContext:createIfMissing:] + 364
4 CoreData 0x00007fff82d4f809 -[PFUbiquityPeerRange(UbiquityMethods) loadFromStoreMetadataDictionary:] + 105
5 CoreData 0x00007fff82d80372 -[PFUbiquityStoreMetadataMedic recoverPeerRangesWithError:] + 418
6 CoreData 0x00007fff82d80ab5 -[PFUbiquityStoreMetadataMedic recoverMetadataWithError:] + 1749
7 CoreData 0x00007fff82d831dc -[PFUbiquitySetupAssistant performPostStoreSetupWithStore:error:] + 732
8 CoreData 0x00007fff82c04001 -[NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:] + 3537
9 MyApp 0x000000010323de60 -[AppDelegate persistentStoreCoordinator] + 4224
10 MyApp 0x000000010323e43f -[AppDelegate managedObjectContext] + 95
11 Foundation 0x00007fff863b5384 _NSGetUsingKeyValueGetter + 62
12 Foundation 0x00007fff863b5339 -[NSObject(NSKeyValueCoding) valueForKey:] + 392
13 Foundation 0x00007fff863d4dc6 -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 348
14 AppKit 0x00007fff87fb1ae2 -[NSBinder _valueForKeyPath:ofObject:mode:raisesForNotApplicableKeys:] + 654
15 AppKit 0x00007fff87fb17cc -[NSBinder valueForBinding:resolveMarkersToPlaceholders:] + 171
16 AppKit 0x00007fff87fb143a -[NSObjectParameterBinder _updateObject:observedController:observedKeyPath:context:] + 1181
17 AppKit 0x00007fff87fa3777 -[NSObject(NSKeyValueBindingCreation) bind:toObject:withKeyPath:options:] + 591
18 AppKit 0x00007fff87f9ca89 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1079
19 AppKit 0x00007fff87f9309f loadNib + 322
20 AppKit 0x00007fff87f9259c +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 217
21 AppKit 0x00007fff87f924b7 +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 141
22 AppKit 0x00007fff87f923fa +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 364
23 AppKit 0x00007fff882059b3 NSApplicationMain + 398
24 MyApp 0x0000000103239522 main + 34
25 MyApp 0x00000001032394f4 start + 52
26 ??? 0x0000000000000003 0x0 + 3
)
terminate called throwing an exception(lldb)
當我不添加NSPersistentStoreUbiquitousContentNameKey
和NSPersistentStoreUbiquitousContentURLKey
選擇到店裏一切正常沒有問題。我只在每次第二次應用程序啓動時纔得到此例外。出於測試目的(因爲我認爲問題可能與併發有關),我從主NIB文件中刪除了所有核心數據訪問和綁定,並嘗試以編程方式在applicationDidFinishLaunching:
方法內訪問核心數據堆棧。在第一次測試中,我直接做了這個,第二次在延遲10秒後執行選擇器(managedObjectContext
)。兩次測試都會在每次第二次應用程序啓動時產生相同的例外
(略縮短這個例子)managedObjectContext
方法是這樣的:
- (NSManagedObjectContext *)managedObjectContext
{
if (managedObjectContext_)
{
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
if (!coordinator)
{
return nil;
}
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc performBlockAndWait:
^{
moc.mergePolicy = [[NSMergePolicy alloc]
initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType];
[moc setPersistentStoreCoordinator:coordinator];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChangesFrom_iCloud:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:coordinator];
}];
managedObjectContext_ = moc;
return managedObjectContext_;
}
的persistentStoreCoordinator
相關部分是:
NSMutableDictionary *storeOptions = [NSMutableDictionary dictionary];
[storeOptions setObject:[NSNumber numberWithBool:YES]
forKey:NSMigratePersistentStoresAutomaticallyOption];
[storeOptions setObject:[NSNumber numberWithBool:YES]
forKey:NSInferMappingModelAutomaticallyOption];
NSURL *url = [NSURL fileURLWithPath:[applicationSupportDirectory
stringByAppendingPathComponent:kJCMyAppDatabaseFilename]];
NSURL *ubiquityURL = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
if (ubiquityURL)
{
JCDLog(@"User has iCloud enabled.");
[storeOptions setObject:@"com.juicycocktail.myapp"
forKey:NSPersistentStoreUbiquitousContentNameKey];
[storeOptions setObject:[NSURL fileURLWithPath:[[ubiquityURL path]
stringByAppendingPathComponent:kJCMyAppDatabaseFilename]]
forKey:NSPersistentStoreUbiquitousContentURLKey];
}
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:mom];
NSPersistentStoreCoordinator *psc = persistentStoreCoordinator_;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
(dispatch_block_t)^{
[psc lock];
if (![psc addPersistentStoreWithType:kJCMyAppStoreType
configuration:nil URL:url options:storeOptions error:&error])
{
dispatch_async(dispatch_get_main_queue(),
^{
[[NSApplication sharedApplication] presentError:error];
persistentStoreCoordinator_ = nil;
return;
});
}
[psc unlock];
dispatch_async(dispatch_get_main_queue(),
^{
JCDLog(@"asynchronously added persistent store!");
[[NSNotificationCenter defaultCenter]
postNotificationName:@"RefetchAllDatabaseData"
object:self userInfo:nil];
});
});
return persistentStoreCoordinator_;
我猜測,PFUbiquityPeer類可能已經事核心數據的事務日誌保存在iCloud的移動文檔文件夾中,但我仍然找不到這個問題的真正原因。任何幫助如何跟蹤這個異常的根源,高度讚賞,因爲我已經瘋了。尤其是解決方法或解決方案對我來說會非常有幫助。我也很高興,如果有人有一個提示如何至少追查這個例外。
注意:如果這是一個API錯誤(rdar:// 10892613),我也提交了一個錯誤。
哇我重新啓動電腦,它也工作!重新啓動之前,我的代碼會停止將NSPersistentStoreUbiquitousContentNameKey添加到migratePersistentStore方法的位置 – coolcool1994 2018-01-12 02:29:08