0

我遇到了使用NSFetchedResultsController的問題,我無法阻止它凍結用戶界面。初始抓取很快發生,但是當我觸發任何錯誤時,滾動表格視圖時會導致凍結。我只使用測試8種元素和正在使用StackMob我的後端NSFetchedResultsController凍結UI

這裏就是我宣佈NSFetchedResultsController

- (NSFetchedResultsController *)fetchedResultsController { 

    if (_fetchedResultsController != nil) { 
     return _fetchedResultsController; 
    } 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Post" 
            inManagedObjectContext:_managedObjectContext]; 
    [fetchRequest setEntity:entity]; 


    NSSortDescriptor *sort = [[NSSortDescriptor alloc] 
          initWithKey:@"createddate" ascending:NO]; 
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]]; 

    NSFetchedResultsController *theFetchedResultsController = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
            managedObjectContext:_managedObjectContext 
             sectionNameKeyPath:nil 
               cacheName:nil]; 
    _fetchedResultsController = theFetchedResultsController; 

    return _fetchedResultsController; 
} 

這裏是我的viewDidLoad:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIColor* backgroundImage = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:BACKGROUND_IMAGE_TAN]]; 
    [[self view] setBackgroundColor:backgroundImage]; 
    [[self tableView] setSeparatorStyle:UITableViewCellSeparatorStyleNone]; 
    _managedObjectContext = [[self.appDelegate coreDataStore] contextForCurrentThread]; 

    NSError *error;  
    if (![[self fetchedResultsController] performFetch:&error]) { 
     // Update to handle the error appropriately. 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); // Fail 
    } 
} 

這裏是我的cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"CCCell"; 
    CCCell *cell = (CCCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CCCell" owner:nil options:nil]; 
     cell = [topLevelObjects objectAtIndex:0]; 
     [cell setDelegate:self]; 
     [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
    } 

    Post* post = (Post*)[_fetchedResultsController objectAtIndexPath:indexPath]; 

    // 
    //IF I UNCOMMENT THIS LINE IT LOCKS THE UI 
    // 
    //NSLog(@"%@", [post valueForKey:@"price"]); 
    return cell; 
} 

如果我取消註釋指定的行它會導致非常緩慢滾動

我試圖圍繞呼叫,像這樣

dispatch_queue_t coreDataThread = dispatch_queue_create("com.YourApp.YourThreadName", DISPATCH_QUEUE_SERIAL); 

dispatch_async(coreDataThread, ^{ 
    Post* post = (Post*)[_fetchedResultsController objectAtIndexPath:indexPath]; 
    NSLog(@"%@", [post valueForKey:@"price"]); 
}); 

來電,但就要花很長的時間20秒左右

回答

1

設置您取一個fetchBatchSize請求的數量約等於表格在屏幕上的行數的兩倍。這將節省不得不加載整個數據集。另請參閱NSFetchedResultsController關於cacheName的文檔。順便說一下,你的[[self.appDelegate coreDataStore] contextForCurrentThread]看起來很可疑。所有這些UI代碼將在主線程上執行,因此要求另一個對象生成每個線程的MOC幾乎肯定沒有必要。

您的GCD代碼不正確,因爲您現在同時擁有主UI線程和您的GCD coreDataThread與同一NSFetchedResultsController進行對話,因此兩個線程正在與同一個MOC進行對話。

如果你對Core Data性能感到困惑,那麼值得開啓SQL日誌記錄。

-com.apple.CoreData.SQLDebug 1 

作爲命令行參數,通過Scheme Editor啓用。