2011-12-04 8 views
6

私はテーブルビューでNSFetchedResultsControllerを処理しようとしていますが、セットアップを正しく行うための最善の努力にもかかわらず、常に行が返されません。 Finderでデータストアを開いて、SQLiteエディタを使って実際にレコードがたくさんあることを確認しましたが、常にゼロを返します。私は何が欠けていますか?コントローラのNSFetchedResultsControllerは常にローを返しません

カスタムゲッター:viewDidLoad

- (NSFetchedResultsController *)fetchedResultsController { 
    if (fetchedResultsController_ != nil) { 
     return fetchedResultsController_; 
    } 

    RBGameItemController* itemController = [RBGameItemController sharedInstance]; 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"GameItem" inManagedObjectContext:itemController.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

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

    [fetchRequest setFetchBatchSize:20]; 

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

    [sort release]; 
    [fetchRequest release]; 
    [theFetchedResultsController release]; 

    return self.fetchedResultsController; 
} 

Iは、データをフェッチしています:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    NSError *error = nil; 
    if (![self.fetchedResultsController performFetch:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    } 
} 

フェッチ結果デリゲート:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates. 
    [self.tableView beginUpdates]; 

    NSLog(@"controllerWillChangeContent"); 
} 


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 
    NSLog(@"controller:didChangeObject:"); 
    UITableView *tableView = self.tableView; 

    switch(type) { 

     case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      break; 

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      // Reloading the section inserts a new row and ensures that titles are updated appropriately. 
      [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { 
    NSLog(@"controller:didChangeSection:"); 
    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    NSLog(@"controllerDidChangeContent:"); 
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates. 
    [self.tableView endUpdates]; 
} 

Iはセクションの両方の方法を実装してい行番号:セクションの場合は1、行の場合は0を返します。

- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { 
    int sections = [[self.fetchedResultsController sections] count]; 
    NSLog(@"sections=%i", sections); 
    return sections; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; 
    int rows = [sectionInfo numberOfObjects]; 

    NSLog(@"rows=%i", rows); 

    return rows; 
} 

答えて

11

フェッチリクエストを使用して手動でクエリを実行して、期待どおりの結果が得られたことを確認しましたか?カスタムfetchedResultsControllerでやってみてください:

NSArray *entities = [itemController.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
NSLog(@"%d",entities.count); 

をして戻ってくるものを参照してください。

また、キャッシュなしでfetchedRequestControllerを設定してみてください。アプリケーションの他の部分で同じキャッシュを名前で再利用している可能性がありますか?

+1

だから私はフェッチんでしたし、それは私が期待していた行が返されました。私がやったことは、cacheNameに 'nil'を渡すことでした。これは問題ではないはずです。なぜなら、これは現在NSFetchedResultsControllerを持っている唯一の場所なので、なぜ問題があるのか​​困惑しています。 –

+0

@WayneHartmanがキャッシュ名にnilを渡すことで、この問題が解決されました。私はアプリ内の他の場所にキャッシュを使用しないので、ここで指定する理由が混乱してゼロの結果が得られました。 – deepwinter

0

cacheNameにnilを渡すと、私の問題も解決しました。デリゲートへ

5

割り当て:

self.fetchedResultsController.delegate = self; 

最終ライン:

return self.fetchedResultsController; 

これらは、このメソッドの円形の呼び出しになります。このようなコードは書かないでください。

この呼び出しのcritcalポイントは、managedObjectContext、sortDescriptor、およびエンティティです。だから、これらのどれもがゼロでないこと、そして値があなたの期待するものであることを確かめてください。

static NSString *const NSString *kMyFetchedResultsControllerCacheName = @"RootCache"; 



- (NSFetchedResultsController *)fetchedResultsController { 
    if (_fetchedResultsController == nil) { 
     [NSFetchedResultsController deleteCacheWithName:]; 
     RBGameItemController* itemController = [RBGameItemController sharedInstance]; 

     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
     NSEntityDescription *entity = [NSEntityDescription entityForName:NSStringFromClass([GameItem class]) inManagedObjectContext:itemController.managedObjectContext]; 
     [fetchRequest setEntity:entity]; 

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

     [fetchRequest setFetchBatchSize:20]; 

     NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:itemController.managedObjectContext sectionNameKeyPath:nil cacheName:kMyFetchedResultsControllerCacheName]; 
     self.fetchedResultsController = fetchedResultsController; 
     fetchedResultsController.delegate = self; 
    } 

    return _fetchedResultsController; 
} 

は最後に、あなたは常に、おそらくviewDidLoadで、performFetchが呼び出されたことを確認する必要があります。

NSError *error = nil; 
[self.fetchedResultsController performFetch:&error]; 
if (error != nil) { 
    NSLog(@"%@", error.localizedDescription); 
} 
+1

私は、同じことをするために1年半前に自分自身を確かに叩くだろう。 ;) –

関連する問題