2013-10-08 78 views
2

我有一個NSFetchedResultsController -backed UICollectionViewController由對象列表填充。每個對象都有一個名爲deleted的BOOL屬性。我的提取控制器使用以下謂詞來過濾我的對象。是否有可能有一個NSFetchedResultsController刪除對象的一個​​對象的屬性不滿足它的謂詞?

[NSPredicate predicateWithFormat:@"deleted == NO"]; 

我的問題是,當我通過標記爲deleted = @YES來刪除對象。隨後的didChangeObject:方法告訴我,對象是已更新不是已刪除。並且該對象不會從集合視圖中刪除。如果我退出並重新加載我的應用程序,則該對象不會顯示在集合視圖中,這是正確的行爲。

有什麼,我做錯了,或者這是預期的行爲NSFetchedResultsController?這裏要求

更新是代碼:

讀取控制器配置:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deleted == %@", @NO]; 
NSSortDescriptor *timestampSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:NO]; 
NSSortDescriptor *prioritySortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"priority" ascending:NO]; 
NSManagedObjectContext *managedObjectContext = [NSManagedObjectContext MR_defaultContext]; 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:[GYNotification description] inManagedObjectContext:managedObjectContext]; 
[request setEntity:entity]; 
[request setIncludesSubentities:YES]; 
[request setSortDescriptors:sortDescriptors];  
[request setPredicate:predicate]; 

NSFetchedResultsController *aFetchedResultsController = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:request 
              managedObjectContext:managedObjectContext 
              sectionNameKeyPath:sectionNameKeyPath 
                 cacheName:nil]; 

然後取數據控制器的委託方法:

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath 
    forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath { 
    NSMutableDictionary *change = [NSMutableDictionary new]; 
    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      change[@(type)] = newIndexPath; 
      break; 
     case NSFetchedResultsChangeDelete: 
      change[@(type)] = indexPath; 
      break; 
     case NSFetchedResultsChangeUpdate: 
      change[@(type)] = indexPath; 
      break; 
     case NSFetchedResultsChangeMove: 
      change[@(type)] = @[indexPath, newIndexPath]; 
      break; 
    } 
    [_objectChanges addObject:change]; 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    if ([_objectChanges count] > 0) { 
     [self.collectionView performBatchUpdates:^{ 
      for (NSDictionary *change in _objectChanges) { 
       [change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) { 
        NSFetchedResultsChangeType type = [key unsignedIntegerValue]; 
        switch (type) 
        { 
         case NSFetchedResultsChangeInsert: 
          [self.collectionView insertItemsAtIndexPaths:@[obj]]; 
          break; 
         case NSFetchedResultsChangeDelete: 
          [self.collectionView deleteItemsAtIndexPaths:@[obj]]; 
          break; 
         case NSFetchedResultsChangeUpdate: 
          [self.collectionView reloadItemsAtIndexPaths:@[obj]]; 
          break; 
         case NSFetchedResultsChangeMove: 
          [self.collectionView moveItemAtIndexPath:obj[0] toIndexPath:obj[1]]; 
          break; 
        } 
       }]; 
      } 
     } completion:nil]; 
    } 

    [_objectChanges removeAllObjects]; 
} 
+1

看起來像預期的行爲,因爲你實際上並沒有刪除對象,但_update_屬性,你創建和哪些NSFetchedResultsController一無所知。如果使用managedObjectContext的deleteObject:方法執行此操作,NSFetchedResultsController可正確檢測到對象刪除,但它如何知道「已刪除」屬性? –

+0

顯示FRC配置和委託方法的更多代碼。 – Wain

+3

[NSFetchedResultsController更新錯誤的更新類型]的可能重複(http://stackoverflow.com/questions/16283252/nsfetchedresultscontroller-updating-with-wrong-update-type) - 答案:你不能調用你的屬性「刪除」。 –

回答

5

這種行爲聽起來像我期望從NSFetchedResultsController。你真的只是對你的一個對象進行更新。它被命名爲deleted的事實沒有區別。實際上,在我看來,將其稱爲deleted有點危險,因爲NSManagedObject已經有一個isDeleted方法。

聽起來好像你想從視圖中隱藏某些管理對象而不真正刪除它們。我會建議將deleted屬性重命名爲shouldBeVisiblemarkedForDeletion。這樣的意圖是更清楚一點,不會有太多的混淆,你的對象真的在什麼狀態。

+1

通過調用除刪除以外的其他屬性,修復了問題。非常感謝。 –

+0

遇到完全相同的問題,從來沒有考慮到屬性名稱會導致問題。謝謝! – bmueller

1

您需要刪除管理對象像這樣:

NSManagedObjectContext *context = ... ; 
NSManagedObject *managedObjectToDelete = ... ; 

[context deleteObject:managedObjectToDelete]; 

只有這樣你的NSFetchedResultsController纔會檢測到刪除。

+0

我通常會刪除它們,但在這種情況下,我需要保留它們。 –

相關問題