Çekirdek Veriler - iş parçacığı başına bir Yönetilen Nesne Bağlamı söz konusu olduğunda altın bir kural vardır. Yönetilen nesne bağlamları iş parçacığı güvenli değildir, bu nedenle arka plan görevinde çalışıyorsanız, ana iş parçacığını UI işlemleriyle iş parçacıklarının çakışmasını önlemek için kullanın veya işi yapmak için yeni bir bağlam oluşturun. Eğer iş işe yarayacaksa Birkaç saniye sonra UI'nizi kilitlemek için ikincisini yapmalısınız. Bunu yapmak için
yeni bağlam oluşturmak ve ana bağlam olarak bunu aynı kalıcı depo vermek: Yapmanız gereken
NSManagedObjectContext *backgroundContext = [[[NSManagedObjectContext alloc] init] autorelease];
[backgroundContext setPersistentStoreCoordinator:[mainContext persistentStoreCoordinator]];
Do olursa olsun operasyonlarını, yeni bağlam idare gerektiğini tasarruf sonra ne zaman Bildirimi kaydedin ve değişiklikleri ana içeriğinize mergeChangesFromContextDidSaveNotification:
mesajıyla birleştirin. kaydetmek notifcation Handling
/* Save notification handler for the background context */
- (void)backgroundContextDidSave:(NSNotification *)notification {
/* Make sure we're on the main thread when updating the main context */
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
withObject:notification
waitUntilDone:NO];
return;
}
/* merge in the changes to the main context */
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
/* ... */
/* Save the background context and handle the save notification */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:backgroundContext];
[backgroundContext save:NULL];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:syncContext];
ve birleştirme aksi takdirde ana UI/bağlam değişiklikleri yapıldıkları görmezsiniz önemlidir: Kod şöyle görünmelidir. Birleştirerek ana getirmeResultsController vb. Etkinliklerinizi değiştirecek ve kullanıcı arayüzünü beklediğiniz gibi güncelleyecektir.
Dikkat edilmesi gereken diğer önemli bir nokta da, NSManagedObject örneklerinin yalnızca alındıkları bağlamda kullanılabilmesidir. İşleminizin bir nesneye başvurması gerekiyorsa, nesneyi objectID
işlemine geçirmeniz ve existingObjectWithID:
'u kullanarak yeni bağlamdan bir NSManagedObject örneğini yeniden getirmeniz gerekir. Yani bir şey gibi:
/* This can only be used in operations on the main context */
MyNSManagedObject *objectInMainContext =
[self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
/* This can now be used in your background context */
MyNSManagedObject *objectInBackgroundContext =
(MyNSManagedObject *) [backgroundContext existingObjectWithID:[objectInMainContext objectID]];
Peki, benim söylediklerimde, fetchedResultsController kullanmak yerine, yeni bir yönetilen nesne bağlamı oluşturmalıyım (backgro) undManagedObjectContext), gerekli yönetilen nesneyi getirin, gerekli işlemleri gerçekleştirin, yönetilen nesneyi güncelleyin, yönetilen bu nesne bağlamını (backgroundManagedObjectContext) kaydedin ve değişiklikleri ana yönetilen nesne bağlamında yansıtacak şekilde birleştirin. Bu hayatımı çok sefil hale getirecek. – Mustafa
UI'nizdeki öğeleri görüntülemek ve güncellemek için hala getirilen sonuç denetleyicisini kullanabilirsiniz. Size gösterdiğim kod, ihtiyacınız olan herhangi bir işlemi ayrı bir içerikte gerçekleştirmek için gereken her şeydir, başka hiçbir şey değişmemelidir. –
Bu altın kuralın etrafında yollar vardır: https://github.com/adam-roth/coredata-threadsafe. – aroth