5

私は現在、最初の CoreData プロジェクトを作成しようとしていますが、非常に混乱しています。次のコードを使用して、フェッチされた結果コントローラーをセットアップしています。

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil)
        return _fetchedResultsController;

    Singleton *singleton = [Singleton sharedSingleton];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"MapEntity" inManagedObjectContext:[singleton managedObjectContext]];
    [fetchRequest setEntity:entity];

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

    [fetchRequest setFetchBatchSize:8];

    // Finally check the results
    NSError *error;
    NSArray *fetchedObjects = [[singleton managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    for (MapEntity *map in fetchedObjects)
    {
        NSLog(@"Maps present in database: %@", map.sName);
    }


    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[singleton managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

NSLog を入れて、fetchRequest が結果を見つけているかどうかを確認しました。

2013-01-28 11:20:14.735 WildMap_iOS[10931:16a03] Maps present in database: UK Capital Cities
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: The UK
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Testing123
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: TestForPic
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Scottish Map
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Old Scotland
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Old Scotland
2013-01-28 11:20:14.737 WildMap_iOS[10931:16a03] Maps present in database: Old Scotland
2013-01-28 11:20:14.737 WildMap_iOS[10931:16a03] Maps present in database: Field Concatination

ただし、fetchedResultsController を使用して tableView numberOfRowsInSection を次のように設定しようとすると、次のようになります。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];

    return [sectionInfo numberOfObjects];
}

「return [sectionInfo numberOfObjects];」fetchRequest がオブジェクトを正常に取得しているように見えても、nil を返します。

私はこのコードを問題なく使用していましたが、最近 mapEntity (iID) に整数を追加したところ、格納されたデータの構造が変更されたため、シミュレータ データを削除することになりました。データを削除してアプリケーションを再起動すると、コードが機能しなくなりました。

なぜこれが起こっているのかを理解するのを手伝ってくれる人はいますか? 以前は機能していた命名規則ではないと思います.fetchRequestは結果を返しています。

4

2 に答える 2

6

@Levi が提案したことに加えて、インスタンス変数に(または他のテーブル ビュー データ ソース メソッドで)_fetchedResultsController直接アクセスしないでください。numberOfRowsInSection常にプロパティ アクセサーを使用しますself.fetchedResultsController

理由: fetchedResultsControllergetter メソッドは、必要に応じて、フェッチされた結果のコントローラーを作成します。_fetchedResultsController直接アクセスすると、 が返される場合がありnilます。

更新:もう 1 つの問題は、フェッチされた結果コントローラーのキャッシュです。ドキュメントから:

重要: キャッシュを使用している場合 deleteCacheWithName:は、フェッチ要求、その述語、またはそのソート記述子を変更する前に呼び出す必要があります。cacheNameを に設定しない限り、フェッチされた同じ結果コントローラを複数のクエリに再利用しないでください nil
...
可能であれば、コントローラーはキャッシュを使用して、セクションのセットアップとコンテンツの順序付けで実行される作業を繰り返す必要を回避します。キャッシュは、アプリケーションの起動後も維持されます。

そのため、FRC のパラメーターが変更された場合は、キャッシュを使用するcacheName:nilか、キャッシュを削除するようにする必要があります。

于 2013-01-28T12:08:20.353 に答える
1

return _fetchedResultsController;メソッドの行の前にNSFerchedResultsController、リクエストを実行するように指示します。

[self.fetchedResultsController performFetch:NULL];
于 2013-01-28T11:56:22.577 に答える