我創建了一個NSOperationQueue
所有關於一個表的inserting/updating/deleting/searching
的操作。我使用MagicalRecord
進行核心數據操作。但是我在同步時遇到了一些問題。一個簡單的例子如下。NSOperationQueue,CoreData和MagicalRecord同步問題
例如,一個名爲person
的表和一個名爲like
的人內部的列。當用戶點擊一個按鈕時,like
將增加1。我不喜歡它
[SameBackgroundQueue addOperationWithBlock:^{
User *user = [User MR_findFirstWithPredicate:some_predicate];
user.like += 1;
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
[SameBackgroundQueue addOperationWithBlock:^{
[self syncWithServer];//This can take time
}];
}];
然而,如果用戶點擊快,等不正確的,因爲MR_findFirstWithPredicate
可以得到髒記錄。問題源於NSOperationQueue
可以僱員不同的線程,而MR_findFirstWithPredicate
使用當前線程的上下文。因此,它可能會嘗試從不同的NSManagedObjectContext
獲取用戶,因此它將獲取髒數據。
當然,如果我們使用mainQueue
,我們不會有任何問題。但是,我怎樣才能使用後臺線程,並確保我沒有骯髒的記錄問題。似乎整個問題都可以解決,如果我運行在一個特定的線程而不是用戶NSOperationQueue。我應該使用GCD嗎?
在我以前的項目中,我使用
[self createManagedObjectContextWithParent:self.mainQueueManagedObjectContext andConcurrencyType:NSPrivateQueueConcurrencyType];
和
[managedObjectContext save:&error];
if (managedObjectContext.parentContext) {
[managedObjectContext.parentContext performBlock:^{
NSError *parentError = nil;
[managedObjectContext.parentContext save:&parentError];
}];
}
我知道有WWDC視頻談論的NSManagedObjectContext和併發上下文等,但如果我使用這個,我不能使用MagicRecord。
任何建議將不勝感激。
其實我找到一個更有效的方法來做到這一點。如果我做錯了,請糾正我。
我實際上創建了一個共同的單身人士上下文[NSManagedObjectContext MR_context]
爲User OperationQueue共享。所以即使所有的線程訪問相同的上下文,他們也不會弄髒數據。
仍然會有毛刺,例如,如果兩個線程正在改變同一個上下文中的同一個對象會發生什麼。這通常是非常罕見的情況,但我會看到它是如何發生的。我可能會將最大併發線程設置爲1,以避免出現這種情況。我不確定它是否會降低性能。將明天更新進度。
嗨,這可能是一個解決方案。但它會限制後臺隊列的性能。感謝您解決同步問題。我正在盡全力,如跟蹤狀態,並比較修改的時間等。 –
現在,用戶同步功能也使用UserQueue。也許我應該使用另一個隊列UserSyncQueue,以便User CoreData只使用一個併發線程,但UserSyncQueue可以同時佔用多個線程。 –