0

Работает на моем RSS Reader.Почему мой NSManagedObject не сохраняется после [moc save] PerformBlockAndWait?

Моя модель данных примерно состоит из следующей иерархии NSManagedObject:

Category <---->> Feed <---->> Post 

Мое приложение использует следующее:

  • «корневой» NSManagedObjectContext с типом NSPrivateQueueConcurrencyType параллелизмом. Я использую этот MOC для сохранения изменений в NSPersistentStoreCoordinator.

  • a "main" NSManagedObjectContext с NSMainQueueConcurrencyType Тип параллелизма. Я использую этот MOC для подачи моего графического интерфейса.

  • «Местный» NSManagedObjectContext с NSPrivateQueueConcurrencyType Тип параллелизма. Я создаю и использую этот MOC каждый раз, когда я запускаю новые объекты Posts.

Как только загружается MainViewController, он заполняется, если пуст.

В конце метода populate, я убедиться, что все в правильно сохранялось, а также refetch мои данные:

[_mainMOC performBlockAndWait:^{ 
    NSError *error; 
    if (![_mainMOC save:&error]) { 
     NSLog(@"[MainViewController::populate] Error.mainMOC: %@\n%@", [error description], [error userInfo]); 

    } 
    [[_mainMOC parentContext] performBlockAndWait:^{ 
     NSError *error; 
     if (![[_mainMOC parentContext] save:&error]) { 
      NSLog(@"[MainViewController::populate] Error.saveMOC: %@\n%@", [error description], [error userInfo]); 

     } 
    }]; 
    NSLog(@"[MainViewController::populate] OK.saveMOC"); 
}]; 
NSLog(@"[MainViewController::populate] OK.mainMOC"); 
[_mainMOC performBlock:^{ 
    NSError *error; 
    if (![_mainMOC executeFetchRequest:[_fetchedResultsController fetchRequest] error:&error]) { 
     NSLog(@"[MainViewController::populate] refetch: %@\n%@", [error description], [error userInfo]); 

    } 
}]; 

Несмотря на это, я не могу создать Post S в моих Feed с в специальный `localMOC`` :

NSManagedObjectID *feedID=[f objectID]; 
if ([feedID isTemporaryID]) { 
    NSLog(@"Warning %@ has not yet been persisted!", f.name); 
} 
/* ... */ 
NSManagedObjectContext *localMOC; 
localMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
[localMOC setParentContext:self.mainMOC]; 
/* ... */ 
[localMOC performBlock:^{ 
    NSError *error=nil; 
    Feed *feed=((Feed *)[localMOC existingObjectWithID:feedID error:&error]); 
    if (error) { 
     NSLog(@"[MAsterViewController::fetchPosts] %@\n%@", [error localizedDescription], [error userInfo]); 
     return; 
    } 
/* ... */ 

выше бит кода дает следующий протокол:

2013-11-14 19:24:04.847 uRSS[10907:70b] Warning Maddox has not yet been persisted! 
2013-11-14 19:24:04.847 uRSS[10907:1303] [MAsterViewController::fetchPosts] The operation couldn’t be completed. (Cocoa error 133000.) 

Может ли кто-нибудь сказать мне, что здесь происходит не так? Спасибо!

ответ

0

я, наконец, решить свои проблемы за счет реализации моей экономии дня:

[_localMOC performBlockAndWait:^{ 
    NSError *errLoc=nil; 

    if (![self.mainMOC obtainPermanentIDsForObjects:@[[[_mainMOC insertedObjects]  arrayByAddingObjectsFromArray:[_mainMOC updatedObjects]]] error:&errLoc]) { 
    NSLog(@" ... "); 
    } 

    if (![_localMOC save:&errLoc]) { 
     NSLog(@" ... "); 
    } 
    [_mainMOC performBlockAndWait:^{ 
     NSError *errMain=nil; 
     if (![_mainMOC save:&errMain]) { 
      NSLog(@" ... "); 
     } 
    }] 
}]; 

Обратите внимание, что _mainMOC наблюдается из AppDelegate и будет его изменения асинхронно сохранялось на диск его _saveMOC родителя.

1

Невозможно, чтобы один контекст имел доступ к другому временному «временному» (несохраненному) объекту без какой-либо операции сохранения/изменения.

контекст - блокнот, владеющий только его изменениями, пока он не решит поделиться ими, совершив операцию сохранения (вы также можете прослушивать уведомления об изменении контекста).

В вашем случае:
main контекст создал объект (до возникновения local контекста).
Затем вы пытаетесь получить доступ к этому элементу из контекста local, не сохраняя сначала объект (или получения постоянного идентификатора).

Для выполнения такого рода поток, вам нужно будет, по крайней мере, получить постоянный идентификатор для вас объекта: [self.mainMOC obtainPermanentIDsForObjects:@[f] error:&error]

Примечание:
Несмотря на main MOC быть родителем local контекст с использованием метода existingObjectWithID:error: контекста local будет искать объект только в зарегистрированных объектах контекста local. в противном случае он попытается извлечь из магазина. получение постоянного идентификатора приведет к тому, что контекст local попытается получить доступ к хранилищу (или родительскому контексту) для извлечения объекта.

+0

Здравствуйте, * Спасибо * много за вашу помощь. Итак, я думаю, что мой многократный блок 'performBlockAndWait ... save'' не имеет никакого эффекта? – mirx

+1

Поскольку контекст 'local' не сохранялся и не смог изменить объект, то нет. но все изменения, внесенные в «основной» контекст, будут сохраняться. –

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