我一直在使用RSS閱讀器,使用核心數據進行緩存。像很多人一樣,我想避免重複輸入,這導致我出現了this的問題,並且還有this one。 但是,我還想要另一件事,我還希望讓用戶能夠刪除文章,並避免在刷新Feed時再次添加已刪除的文章,即如果刪除的文章仍然存在於Feed中。所以,我現在的解決方案是,在託管對象上下文中維護另一個實體,並使用唯一標識符(我如何識別Feed中的每個項目)刪除文章,我只是將要刪除的文章的標識符添加到該實體,並檢查它。核心數據,重複和刪除的RSS條目
現在,我寫了一段代碼來完成上述所有操作。每次在解析過程中解析Feed中的新項目時,都會運行此代碼。
dispatch_queue_t checkQueue = dispatch_queue_create("com.feedreader.backgroundchecking", NULL);
dispatch_async(checkQueue,^{
NSMutableArray *mutablesortedArticles = [NSMutableArray arrayWithArray:self.feeds.sortedArticles];
if (!mutablesortedArticles) {
// Handle the error.
}
if ([[mutablesortedArticles valueForKey:@"identifier"]
containsObject:article.identifier]) {
NSLog(@"This article already exists");
return;
}else {
NSMutableArray *mutabledeletedArticles = [NSArray arrayWithArray:self.alldeletedArticles];
if (!mutabledeletedArticles) {
// Handle the error.
}
if ([mutabledeletedArticles valueForKey:@"identifier"]
containsObject:article.identifier]) {
NSLog(@"This article has been deleted");
return;
}else {
Article *newArticle = [NSEntityDescription insertNewObjectForEntityForName:@"Article" inManagedObjectContext:self.managedObjectContext];
newArticle.title = article.title;
newArticle.date = article.date;
newArticle.link = article.link;
newArticle.summary = article.summary;
newArticle.image = article.image;
newArticle.identifier = article.identifier;
newArticle.updated = article.updated;
newArticle.content = article.content;
newArticle.feed = self.feed;
dispatch_async(dispatch_get_main_queue(),^{
NSError *error = nil;
[self.managedObjectContext save:&error];
if (error) {
NSLog(@"%@", error);
}
});
}
}
});
兩者,self.feeds.sortedArticles和self.alldeletedArticles解析開始之前從被管理對象的上下文中取出。
我的問題開始於此代碼運行時,UI凍結1-2秒(我在託管對象上下文中有超過500篇文章的Feed中嘗試過)。所以,我想我的問題是,是否有更有效的方式來做我想在這裏做的事情,希望不會凍結UI? 也許更好的處理被刪除的文章?
+1好的建議使用*查找或創建模式*。但是我沒有看到後臺線程@SamJ的上下文每個線程都需要創建自己的上下文。你可以通過它們的'NSManagedObjectID'在線程之間共享對象。 –
@flexaddicted我實際上並沒有在後臺線程中對託管對象上下文做任何事情。我在後臺線程中做的唯一的事情是檢查已經存在的數組(以前從主線程的託管對象上下文中獲取)用於退出和刪除的文章,並創建一個新條目,將其保存到主要的託管對象上下文線。後臺線程的目的就是避免凍結UI。 –
@SamJ .: flexaddicted是對的:你可以在後臺線程中調用'insertNewObjectForEntityForName'。但是所有的核心數據操作都必須在與上下文關聯的線程/隊列上完成。 –