Когда вы используете NSPrivateQueueConcurrencyType
, вам нужно сделать что-либо , которое касается этого контекста или , любой объект, принадлежащий этому контексту, внутри метода -performBlock:
.
Ваш код выше недопустим, так как вы передаете эти объекты обратно в основную очередь. Новый API помогает вам решить эту проблему: вы создаете один контекст, связанный с основной очередью, то есть с NSMainQueueConcurrencyType
:
// Assume we have these two context (They need to be set up. Assume they are.)
NSManagedObjectContext *mainMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
NSManagedObjectContext *backgroundMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
// Now this can safely be called from ANY thread:
[backgroundMOC performBlock:^{
NSArray *results = [backgroundMOC executeFetchRequest:request error:nil];
for (NSManagedObject *mo in results) {
NSManagedObjectID *moid = [mo objectID];
[mainMOC performBlock:^{
NSManagedObject *mainMO = [mainMOC objectWithID:moid];
// Do stuff with 'mainMO'. Be careful NOT to use 'mo'.
}];
}
}];
Это становится менее запутанным, если вы переместите внутренний вызов [mainMOC performBlock:]
в его собственный метод. Вы также можете захотеть передать массив идентификаторов объектов обратно в контекст основного потока вместо того, чтобы выполнять блок для каждого идентификатора объекта. Это зависит от ваших потребностей.