2012-02-19 1 views
0

Когда я добавляю постоянное хранилище с NSPersistentStoreUbiquitousContentNameKey и NSPersistentStoreUbiquitousContentURLKey, мое приложение сбрасывается каждый второй раз с исключением. Это происходит во время вызова addPersistentStoreWithType:configuration:URL:options:error:Исключение с PFUbiquityPeer, связанное с добавлением постоянного хранилища с Core Data & iCloud

Трассировка стека выглядит следующим образом:

*** 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 и попытался получить доступ к стеку Core Data программно внутри метода applicationDidFinishLaunching:. В первом тесте я сделал это напрямую, во второй раз я выполнил селектор (managedObjectContext) после задержки 10 секунд. Оба теста привели к тому же исключению при каждом запуске второго приложения.

The (немного укоротить для этого примера) 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 мог бы что-то делать с журналами транзакций Core Data, которые хранятся в папке мобильных документов iCloud, но я до сих пор не могу найти реальную причину этой проблемы. Любая помощь, как отслеживать корень этого исключения, очень ценится, поскольку я уже получаю орехи. Особенно обходным решением или даже решением было бы очень полезно для меня. Я также рад, если кто-то подскажет, как по крайней мере отследить это исключение.

Примечание: Я также зарегистрировал ошибку в случае, если это ошибка API (rdar: // 10892613).

ответ

1

Перезагрузка OS X решила проблему. Это напоминает мне IT Crowd running gag.

+1

wow Я перезапустил компьютер, и он тоже работал! Перед перезагрузкой мой код остановится, когда я добавлю NSPersistentStoreUbiquitousContentNameKey в метод migratePersistentStore – coolcool1994

Смежные вопросы