0

NSFetchedResultsController の使用に問題があり、UI のフリーズを止めることができません。最初のフェッチはすぐに行われますが、障害が発生すると、テーブル ビューをスクロールするときにフリーズします。テストには 8 つの要素のみを使用し、バックエンドには StackMob を使用しています

ここで、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秒ほどの非常に長い時間がかかります

4

1 に答える 1

1

fetchBatchSizeテーブルが画面上に表示する行数の約 2 倍に等しいフェッチ リクエストを設定します。これにより、データセット全体をロードする必要がなくなります。NSFetchedResultsControllerのドキュメントも参照してくださいcacheName

ところで、あなた[[self.appDelegate coreDataStore] contextForCurrentThread]は不審に見えます。この UI コードはすべてメイン スレッドで実行されるため、別のオブジェクトにスレッドごとの MOC を生成するように要求する必要はほとんどありません。

coreDataThreadメイン UI スレッドと GCD の両方が同じ と通信しているため、GCD コードは正しくありませんNSFetchedResultsController。したがって、2 つのスレッドが同じ MOC と通信しています。

Core Data のパフォーマンスに困惑したことがある場合は、SQL ロギングを有効にする価値があります。

-com.apple.CoreData.SQLDebug 1

コマンドライン引数として、Scheme Editor で有効にします。

于 2013-03-27T00:23:39.217 に答える