5

更新3空のデータストアで初めて実行された後のログです。 FRCフェッチことNSFetchedResultsControllerを使用したUITableViewで2回目の時間が読み込まれない

2013-02-07 20:57:06.708 Five Hundred Things[14763:c07] mainMOC = <NSManagedObjectContext: 0x7475a90> 
2013-02-07 20:57:06.711 Five Hundred Things[14763:1303] Import started 
2013-02-07 20:57:06.712 Five Hundred Things[14763:1303] backgroundMOC = <NSManagedObjectContext: 0x8570070> 
2013-02-07 20:57:06.717 Five Hundred Things[14763:c07] FRC fetch performed 
2013-02-07 20:57:06.718 Five Hundred Things[14763:c07] numberOfSectionsInTableView returns 1 
2013-02-07 20:57:06.720 Five Hundred Things[14763:c07] numberOfSectionsInTableView returns 1 
2013-02-07 20:57:06.720 Five Hundred Things[14763:c07] numberOfRowsInSection returns 0 
2013-02-07 20:57:06.728 Five Hundred Things[14763:1303] call contextDidSave 
2013-02-07 20:57:06.736 Five Hundred Things[14763:1303] call contextDidSave 
2013-02-07 20:57:06.736 Five Hundred Things[14763:c07] numberOfSectionsInTableView returns 1 
2013-02-07 20:57:06.737 Five Hundred Things[14763:c07] numberOfSectionsInTableView returns 1 
2013-02-07 20:57:06.737 Five Hundred Things[14763:c07] numberOfRowsInSection returns 5 
2013-02-07 20:57:06.758 Five Hundred Things[14763:1303] call contextDidSave 
2013-02-07 20:57:06.759 Five Hundred Things[14763:1303] Refresh complete 
2013-02-07 20:57:06.759 Five Hundred Things[14763:c07] numberOfSectionsInTableView returns 1 
2013-02-07 20:57:06.760 Five Hundred Things[14763:c07] numberOfSectionsInTableView returns 1 
2013-02-07 20:57:06.761 Five Hundred Things[14763:c07] numberOfRowsInSection returns 5 

注が行われ、セクションの行数は0であるが、第2 contextDidSave後、データストア内のカテゴリの数と一致する5に変わり。 FRCが初期化され、直後のカテゴリは、彼らがFRCに実際にあることを示すためにログインしている

2013-02-07 21:01:11.578 Five Hundred Things[14800:c07] mainMOC = <NSManagedObjectContext: 0x8225650> 
2013-02-07 21:01:11.581 Five Hundred Things[14800:1303] Import started 
2013-02-07 21:01:11.582 Five Hundred Things[14800:1303] backgroundMOC = <NSManagedObjectContext: 0x7439850> 
2013-02-07 21:01:11.592 Five Hundred Things[14800:c07] FRC fetch performed 
2013-02-07 21:01:11.594 Five Hundred Things[14800:c07] cat = Attraction 
2013-02-07 21:01:11.594 Five Hundred Things[14800:c07] cat = Beverage 
2013-02-07 21:01:11.595 Five Hundred Things[14800:c07] cat = Entertainment 
2013-02-07 21:01:11.595 Five Hundred Things[14800:c07] cat = Hotel 
2013-02-07 21:01:11.596 Five Hundred Things[14800:c07] cat = Restaurant 
2013-02-07 21:01:11.597 Five Hundred Things[14800:c07] numberOfSectionsInTableView returns 1 
2013-02-07 21:01:11.598 Five Hundred Things[14800:c07] numberOfSectionsInTableView returns 1 
2013-02-07 21:01:11.599 Five Hundred Things[14800:c07] numberOfRowsInSection returns 0 
2013-02-07 21:01:11.602 Five Hundred Things[14800:1303] call contextDidSave 
2013-02-07 21:01:11.610 Five Hundred Things[14800:1303] call contextDidSave 

:クラッシュとセカンドランで

は、ここにログです。ただし、セクションの行数は0であり、決して更新されません。代わりに、下のスタックでアプリがクラッシュします。 3回目以降の実行で

、これは、ログは次のようになります。

2013-02-07 21:03:55.560 Five Hundred Things[14815:c07] mainMOC = <NSManagedObjectContext: 0x8128860> 
2013-02-07 21:03:55.563 Five Hundred Things[14815:1e03] Import started 
2013-02-07 21:03:55.564 Five Hundred Things[14815:1e03] backgroundMOC = <NSManagedObjectContext: 0x822b5d0> 
2013-02-07 21:03:55.569 Five Hundred Things[14815:c07] FRC fetch performed 
2013-02-07 21:03:55.571 Five Hundred Things[14815:c07] cat = Attraction 
2013-02-07 21:03:55.572 Five Hundred Things[14815:c07] cat = Beverage 
2013-02-07 21:03:55.572 Five Hundred Things[14815:c07] cat = Entertainment 
2013-02-07 21:03:55.573 Five Hundred Things[14815:c07] cat = Hotel 
2013-02-07 21:03:55.573 Five Hundred Things[14815:c07] cat = Restaurant 
2013-02-07 21:03:55.574 Five Hundred Things[14815:c07] numberOfSectionsInTableView returns 1 
2013-02-07 21:03:55.576 Five Hundred Things[14815:c07] numberOfSectionsInTableView returns 1 
2013-02-07 21:03:55.576 Five Hundred Things[14815:c07] numberOfRowsInSection returns 5 
2013-02-07 21:03:55.581 Five Hundred Things[14815:1e03] call contextDidSave 
2013-02-07 21:03:55.592 Five Hundred Things[14815:1e03] call contextDidSave 
2013-02-07 21:03:55.593 Five Hundred Things[14815:c07] numberOfSectionsInTableView returns 1 
2013-02-07 21:03:55.594 Five Hundred Things[14815:c07] numberOfSectionsInTableView returns 1 
2013-02-07 21:03:55.595 Five Hundred Things[14815:c07] numberOfRowsInSection returns 5 
2013-02-07 21:03:55.606 Five Hundred Things[14815:1e03] call contextDidSave 
2013-02-07 21:03:55.606 Five Hundred Things[14815:1e03] Refresh complete 

これは、動作はセカンドランでどのように見えるべきかです。データはすでにストアに格納されており、セクションの行数は5を返し、カテゴリはすぐにテーブルビューに表示されます。


アップデート2はここでクラッシュが発生する場所であるメインスレッドのスタックトレースです。メインスレッドで発生しているので、私はそれがUITableViewと関係があると考えています。私はNSDictionaryまたはNSMutableDictionaryをUITableViewで使用していません。私の考えは、今度はnumberOfRowsInSectionが2回目の実行で0を返して問題を引き起こしているが、解決方法がわからないということだ。それは、3番目の実行で正しい番号(私が使用しているデータで5)を返し、最初の実行時にデータストアを正しく読み込んでいるように見えるので、2番目の実行で0を返し、更新しないでください。

frame #0: 0x013ede52 libobjc.A.dylib`objc_exception_throw 
frame #1: 0x020330de CoreFoundation`-[__NSDictionaryM setObject:forKey:] + 158 
frame #2: 0x01211d7a CoreData`-[NSFetchedResultsController(PrivateMethods) _preprocessUpdatedObjects:insertsInfo:deletesInfo:updatesInfo:sectionsWithDeletes:newSectionNames:treatAsRefreshes:] + 1994 
frame #3: 0x01212ed7 CoreData`-[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 2455 
frame #4: 0x00b9e4f9 Foundation`__57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 40 
frame #5: 0x0200a0c5 CoreFoundation`___CFXNotificationPost_block_invoke_0 + 85 
frame #6: 0x01f64efa CoreFoundation`_CFXNotificationPost + 2122 
frame #7: 0x00ad2bb2 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 98 
frame #8: 0x01125163 CoreData`-[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 83 
frame #9: 0x011bed2f CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] + 367 
frame #10: 0x01121128 CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _postRefreshedObjectsNotificationAndClearList] + 136 
frame #11: 0x0111f8c0 CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 80 
frame #12: 0x0111f869 CoreData`-[NSManagedObjectContext processPendingChanges] + 41 
frame #13: 0x010f3e38 CoreData`_performRunLoopAction + 280 
frame #14: 0x01f78afe CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 
frame #15: 0x01f78a3d CoreFoundation`__CFRunLoopDoObservers + 381 
frame #16: 0x01f567c2 CoreFoundation`__CFRunLoopRun + 1106 
frame #17: 0x01f55f44 CoreFoundation`CFRunLoopRunSpecific + 276 
frame #18: 0x01f55e1b CoreFoundation`CFRunLoopRunInMode + 123 
frame #19: 0x01f0a7e3 GraphicsServices`GSEventRunModal + 88 
frame #20: 0x01f0a668 GraphicsServices`GSEventRun + 104 
frame #21: 0x00021ffc UIKit`UIApplicationMain + 1211 
frame #22: 0x000022dd Five Hundred Things`main(argc=1, argv=0xbffff31c) + 141 at main.m:16 
frame #23: 0x00002205 Five Hundred Things`start + 53 

アップデート:私は、実際のクラッシュだけではなく無応答を得ることができました。

*キャッチされない例外により 'NSInvalidArgumentException'、理由にアプリを終了: '* setObjectForKey:オブジェクトがnilすることはできません(キー:_ContentChange_OldIndexPathKey')

This SO questionは、私が見つけることができる最も近いですエラーですが、キーの代わりに値がnilであることについて説明します。カテゴリがコアデータストアに保存されているにもかかわらず、すべてのカテゴリに値があるように見えます。整数16 カテゴリ名 - -

エンティティカテゴリ CATEGORY_IDを含むString

それは実体シングと対多の関係を持っていますが、このコードの特定の部分はその関係に何もしていません。 category_idとcategory_nameのみを設定しています。インポートの後半(問題のMOC保存後)は、関係が設定されたときです。インポート操作から当該

コード:

//import categories 

    NSString *categoryPath = [[NSBundle mainBundle] pathForResource:@"category" ofType:@"json"]; 

    NSData *categoryData = [NSData dataWithContentsOfFile:categoryPath]; 

    NSDictionary *categoryResults = [NSJSONSerialization 
            JSONObjectWithData:categoryData 
            options:NSJSONReadingMutableLeaves 
            error:&error]; 

    NSEntityDescription *categoryEntity = [NSEntityDescription entityForName:@"Category" 
               inManagedObjectContext:context]; 

    NSMutableArray *categories = [[NSMutableArray alloc] init]; 

    NSString *categoryPredicateString = [NSString stringWithFormat: @"category_id == $CATEGORY_ID"]; 

    NSPredicate *categoryPredicate = [NSPredicate predicateWithFormat:categoryPredicateString]; 


    for (NSDictionary *categoryKey in categoryResults){ 

     NSFetchRequest *categoryFetchRequest = [[NSFetchRequest alloc] init]; 

     [categoryFetchRequest setEntity:categoryEntity]; 

     NSNumber *categoryID = [NSNumber numberWithInt:[[categoryKey objectForKey:@"category_id"] integerValue]]; 

     [categories addObject:categoryID]; 

     NSDictionary *categoryVariables = [NSDictionary dictionaryWithObject:categoryID forKey:@"CATEGORY_ID"]; 

     NSPredicate *catSubPredicate = [categoryPredicate predicateWithSubstitutionVariables:categoryVariables]; 

     [categoryFetchRequest setPredicate:catSubPredicate]; 

     NSArray *categoryArray = [[NSArray alloc] init]; 
     categoryArray = [context executeFetchRequest:categoryFetchRequest error:&error]; 

     Category *categoryObject = [categoryArray lastObject]; 
     NSNumber *categoryNum = [categoryObject valueForKey:@"category_id"]; 
     NSInteger categoryInt = [categoryNum integerValue]; 

     if (categoryInt != [[categoryKey objectForKey:@"category_id"] integerValue]){ 
      categoryObject = [NSEntityDescription 
           insertNewObjectForEntityForName:@"Category" 
           inManagedObjectContext:context]; 
      categoryObject.category_id = [NSNumber numberWithInt:[[categoryKey objectForKey:@"category_id"] intValue]]; 
     } 
     if (categoryObject.category_name != [categoryKey objectForKey:@"category"]){ 
      categoryObject.category_name = [categoryKey objectForKey:@"category"]; 
     } 

    } 

    //Remove unneeded Categories from Core Data Store 

    NSFetchRequest *removeUnusedCategories = [[NSFetchRequest alloc] init]; 
    [removeUnusedCategories setEntity:categoryEntity]; 
    NSArray *fetchedCategories = [context executeFetchRequest:removeUnusedCategories error:&error]; 

    for (Category *fetchedCategory in fetchedCategories){ 
     if (![categories containsObject:fetchedCategory.category_id]){ 
      [context deleteObject:fetchedCategory]; 
      NSLog(@"Object deleted"); 
     } 
    } 

    if (![context save:&error]) { 
     NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); 
    } 

[context save]背景MOCに発生し、通知センターを通じて(アプリケーションデリゲートで)メインMOCに同期されます。それはNSManagedObjectContextDidSaveNotificationを聞いて、メインMOCでmergeChangesFromContextDidSaveNotification:を実行します。

最初の実行と3番目の実行は完全に機能します。それは常に2回目の実行で発生します。


iOSプロジェクトでCore Dataを使用していますが、これまでのところ1つの問題を除いてうまくいきました。

アプリは、JSONファイルからコアデータストアにデータを取り込み、最初のUITableViewControllerは必要に応じてアニメーションを読み込みます。しかし、アプリケーションが2回目に起動すると、最初のUITableViewは空白になります。私は複数の場所をチェックして、データは2番目の起動が開始されたときにコアデータストアにありますが、UITableViewまたはNSFetchedResultsControllerメソッドのどれも呼び出されません。

最初の起動時に、セクション内の行数は0を返しますが、コアデータストアがロードされた後は、必要なときに5が返されます。 2回目の起動時には、セクション内の行数(1つのセクションのみ)が0を返して更新されません。 3回目以降のすべての起動では、セクション内の行数が5を返します。

UITableViewのcellForRowAtIndexPathとNSFetchedResultsControllerのdidChangeObjectメソッドのどちらも、アプリケーションの2回目の起動時に呼び出されません。 UITableViewControllerは、UITableViewDelegate,UITableViewDataSource、およびNSFetchedResultsControllerDelegateです。

Core Dataガイドラインに示されているように、アプリケーションデリゲートとテーブルビューコントローラは、別のスレッドのバックグラウンドMOCでデータロードが行われている間にマネージオブジェクトコンテキストを共有します。コンテキストのsaveメソッドがmergeChangesFromContextDidSaveNotification:から呼び出されたときに、これらは同期されます。

再生するには、シミュレータからアプリを削除し、一度実行するとデータベースが読み込まれ、アプリが正しく表示されます。私は、アプリを停止し、再度実行し、何も表示されません。私は、アプリケーションを停止し、3回目を実行し、正しく表示されます。

これはすべて、アプリケーションを起動する2回目を除いて正しく動作しているようです。 1回目と3回目は正しく動作します。私は何が欠けていますか?

私のコードは、ここに何を入れるべきか分かりません。 UITableViewControllerの実装から始めましょう。 sectionNameKeyPathは、テーブルビューのセクションを作成するために指定されている場合、私は上記のコメントで想定するものに

@implementation FTWTMasterViewController 

@synthesize managedObjectContext; 
@synthesize categoryController = _categoryController; 
@synthesize catLocViewController; 

- (id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super initWithStyle:style]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (NSFetchedResultsController *)categoryController { 
    if (_categoryController != nil) { 
     return _categoryController; 
    } 

    NSLog(@"tableview MOC = %@", self.managedObjectContext); 

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

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

    [fetchRequest setFetchBatchSize:20]; 

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

    return _categoryController; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.tableView.dataSource = self; 
    self.tableView.delegate = self; 

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

    NSLog(@"Fetch called"); 

    self.title = @"Categories"; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

#pragma mark - Table view data source 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    NSLog(@"number of sections = %lu", (unsigned long)[[self.categoryController sections] count]); 
    return [[self.categoryController sections] count]; 
} 

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

    NSLog(@"numberOfObjects = %lu", (unsigned long)[sectionInfo numberOfObjects]); 
    return [sectionInfo numberOfObjects]; 
} 

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { 
    Category *category = [_categoryController objectAtIndexPath:indexPath]; 
    cell.textLabel.text = category.category_name; 
    NSLog(@"config cell %@", category.category_name); 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSLog(@"tableView setup"); 
    static NSString *CellIdentifier = @"categoryCell"; 

    UITableViewCell *cell = 
    [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    // Set up the cell... 
    [self configureCell:cell atIndexPath:indexPath]; 

    return cell; 
} 

#pragma mark - Table view delegate 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Category *aCategory = [self.categoryController objectAtIndexPath:indexPath]; 

    if (self.catLocViewController == nil){ 
     FTWTCatLocationViewController *aCatLocController = [[FTWTCatLocationViewController alloc] init]; 
     self.catLocViewController = aCatLocController; 
    } 

    self.catLocViewController.selectedCat = aCategory; 
    aCategory = nil; 

    self.catLocViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:self.catLocViewController animated:YES]; 

    self.catLocViewController = nil; 
} 

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

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 

    NSLog(@"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:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      break; 

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray 
               arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray 
               arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { 

    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 { 
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates. 
    [self.tableView endUpdates]; 
} 

@end 
+0

フェッチされた結果コントローラでperformFetch:を呼び出すことはありますか?最初に読み込んだときにmanagedobjectcontextを保存しますか? – wattson12

+0

'performFetch:'は 'viewDidLoad'で呼び出され(上記参照)、各JSONファイルのインポート後にMOCが保存されます。 – scottoliver

+0

viewDidLoadは、アプリを起動するたびに呼び出されます(特に2回目のチェック)。あなたのnumberOfRowsInSectionでは** categoryController **の実際のインスタンス変数にアクセスしているので、これは不思議です。だから、これはゲッターを呼び出さず、遅延インスタンス化によって正しく設定できないかもしれません。 numberOfRows ...でself.categoryControllerを使ってみましたか?ちょうど最初の考え。 – Firo

答えて

8

反して、同様の効果が起こることができる(私は テストプログラムでこれを再現できます)。

は、アプリを初めて起動すると、次の処理が行われます。

  1. 永続的ストアファイル「appname.sqlite」が作成されます。
  2. cacheNameパラメータを設定してテーブルビューのフェッチ結果コントローラを作成すると、セクションキャッシュファイルが作成されます。この時点で、すべてのセクションは空です。
  3. リソースファイルからJSONデータを読み取り、オブジェクトをコンテキストに追加する背景MOCが作成されます。
  4. 背景MOCが保存されます。

(ところで。キャッシュファイルは、アプリケーションバンドル内

Library/Caches/<bundle-id>/.CoreDataCaches/SectionInfoCaches/<tablename>/sectionInfo 

ある。)

アプリが二度目に起動され、セクション情報のキャッシュがあるかどうかをフェッチ結果コントローラチェックまだ有効であるか、または再作成する必要があります。ドキュメントによれば、永続ストアファイルとセクションキャッシュファイルの変更時刻を比較します。

ここで興味深い部分:店舗ファイルの作成(ステップ1)と更新されたコンテキストの保存(ステップ4)が同じ秒に発生した場合、次にストアの変更日ファイルはステップ4のに変更されていません。

したがって、セクションキャッシュファイルは有効と見なされ、は再作成されません。。すべてのセクションが空であったため(ステップ2)、FRCはこのキャッシュされた情報を使用し、空のセクションのみを表示します。

背景MOCが再び開始され、コンテキストが保存されます。今度はストアファイルに新しい変更日付があるため、アプリケーションの3回目の実行でセクションと行が正しく表示されます。

私の "理論"を確認するために、私は最初の実行と2回目の実行の間にストアファイルを手動で "修正"して、変更日を変更しました。すべてのセクションと行が正しく表示されました。

(私はこれをiPhone Simulatorでのみテストしましたが、HFS +ファイルシステムの修正日が通常1秒であるのか、SQLiteで特別なことがあるのか​​分かりません。 。

結論:ストアファイルの作成と変更されたデータの保存が同じ秒で行われる場合、必要に応じてセクション情報キャッシュファイルが再生成されないことがあります。

+0

私は小さなデータセットで作業しており、アップデートは非常に迅速に行われます。私が以前に言及した他のアプリは、ストアファイルの作成とMOCセーブがおそらく同じ秒で起こることはない、もっと大きなデータセットを使用します。 – scottoliver

+0

私の場合にキャッシュを削除するとこの問題が解決しました..しかし、これはちょっと変なバグです。 –

+0

2番目のセクションを正しくロードするにはどうすればよいですか?同じ問題をここに... –

4

同じ問題が発生しました。データをロードしたとき、最初のロードは正常でした。私のアプリを再起動すると、データはテーブルから消えました。これらは私のカウントだった:

self.fetchedResultsController.fetchedObjects:8
[self.fetchedResultsController.sections count]:1
[self.fetchedResultsController.sections[0] numberOfObjects]:0

私はUIでのソートを変更し、再度戻ってそれを変更した後、ソートを変更する機能を持っています、問題は消えてしまいました。これは間違いなくキャッシングの問題を指摘しています。

[NSFetchedResultsController deleteCacheWithName:nil]; 
を呼び出す

は、すべてのキャッシュを削除します。

私も今はキャッシュしないことにしました。私はこれらのテーブルのために私のデータベースに何万ものレコードを格納するとは思わないので、キャッシュが改善するかどうかはわかりません。cacheNamenilに設定すると、NSFetchedResultsControllerのキャッシュは無効になります。

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                    managedObjectContext:self.context 
                     sectionNameKeyPath:sectionIdentifier 
                       cacheName:nil]; 
+0

ありがとう!それは私の日を救った。また、その厄介なエラーの理由。しかし、ついに私はすべてのキャッシュを削除しました。 – Goppinath

関連する問題