在CoreDataTableViewController(由斯坦福大學人員完成的子類)上,我從sqlite數據庫獲取數據。後臺線程的行爲有所不同,具體取決於其調用方法
在模擬器和設備上抓取速度非常快,但爲了使它更老 - 設備友好,我想在背景上執行抓取並在完成時添加微調器。所以我添加了一個預取方法。整個事情是這樣的:
-(void)setupFetchedResultsController{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:self.entity];
request.propertiesToFetch=[NSArray arrayWithObject:self.attribute];
request.resultType=NSDictionaryResultType;
request.returnsDistinctResults=YES;
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"%K != nil", self.attribute];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"%K != ''", self.attribute];
NSPredicate *predicate3= [NSPredicate predicateWithFormat:@"%K contains[cd] %@", self.attribute, self.seachBar.text];
NSArray *prepredicateArray;
if ([self.seachBar.text length]) {
prepredicateArray = [NSArray arrayWithObjects:predicate1, predicate2, predicate3,nil];
}else {
prepredicateArray = [NSArray arrayWithObjects:predicate1, predicate2,nil];
}
request.predicate=[NSCompoundPredicate andPredicateWithSubpredicates:prepredicateArray];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:self.attribute ascending:YES ]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[self performFetch];
}
-(void)prefetch{
UIView *translucentView=[[UIView alloc]initWithFrame:CGRectMake(110, 102, 100, 100)];
[translucentView setCornerRadius:7.0];
translucentView.backgroundColor=[UIColor blackColor];
translucentView.alpha=0.65;
UIActivityIndicatorView *spinner=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.frame=CGRectMake(0, 31.5, 100, 37);
[translucentView addSubview:spinner];
[spinner startAnimating];
[self.view addSubview:translucentView];
dispatch_queue_t fetchQueue = dispatch_queue_create("fetch stuff", NULL);
dispatch_async(fetchQueue, ^{
[self setupFetchedResultsController];
dispatch_async(dispatch_get_main_queue(), ^{
[translucentView removeFromSuperview];
});
});
dispatch_release(fetchQueue);
}
的事情是,當我稱之爲prefetch
方法從viewWillAppear
一切都很好,但是當我把它從一個編輯搜索欄時調用的方法(抓取動態顯示牽強結果,而輸入一個搜索欄),它提供了以下錯誤:
void _WebThreadLockFromAnyThread(bool), 0x6b9b730: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.
這是我的理解是UI的東西應該在主線程上執行,但是我看不出哪裏出錯。
任何指針?提前致謝!
我給這個問題添加了一個ios標籤。不知道這是否正確。 – Gray
您是否真的在舊設備上測試過性能?核心數據的抓取速度非常快,您可以設置抓取請求來限制返回的記錄數,錯誤選項等,這樣會有所幫助。另外,不太確定在後臺線程上創建'NSFetchedResultsController'是個好主意。您是否閱讀過關於核心數據和併發性的Apple文檔?如果你繼續沿着這條路走下去(你應該只用核心數據做最後的手段),那將是有幫助的, – gschandler
是的,我認爲你是可行的。我剛剛重新看了斯坦福大學課程的第14課,在第一張幻燈片中講師說:核心數據不是線程安全的。所以,問題一定是在這裏。人們可以在一個塊上執行它。但正如你所指出的那樣,甚至可能沒有必要。剩下的感謝。 – Marcal