2009-08-24 172 views
3

我不明白爲什麼,在我的生活中,當我向底層數據存儲添加數據時,NSFetchedResultsControllerDelegate方法沒有觸發。如果我重新啓動iPhone應用程序,數據立即顯示。NSFetchedResultsControllerDelegate沒有觸發

我有子類的UITableViewController,符合NSFetchedResultsControllerDelegate:

@interface ProjectListViewController : UITableViewController <NSFetchedResultsControllerDelegate> { 
    NSFetchedResultsController* fetchedResultsController_; 
    NSManagedObjectContext* managedObjectContext_; 
} 

我實例化NSFetchedResultsController和委託設置爲self:

// Controller 
fetchedResultsController_ = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
    managedObjectContext:self.managedObjectContext 
                    sectionNameKeyPath:@"Client" 
                      cacheName:@"ProjectsCache"]; 
fetchedResultsController_.delegate = self; 

我實現委託方法:

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

- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller { ... } 
- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { ... } 
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { ... } 

我創建了我希望保存的實體:

Project* newProject = [NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:self.managedObjectContext]; 
ProjectDetailViewController* detail = [[ProjectDetailViewController alloc] initWithStyle:UITableViewStyleGrouped 
                       delegate:self 
                       selector:@selector(finishedAdding:) 
                       project:newProject]; 

後來,我保存:

- (void)save { 
    // NSLog(@"ProjectDetailViewController.save"); 
    self.project.name = projectNameTextField_.text; 
    NSError* error; 
    BOOL b = [self.project.managedObjectContext save:&error]; 
    if (!b) { 
     NSLog(@"Error saving project!"); 
    } else { 
     NSLog(@"Project was successfully saved."); 
     [delegate_ performSelector:selector_ withObject:self.project]; 
    } 
    [self dismissModalViewControllerAnimated:YES]; 
} 

這一切都工作得很好,除了事實,我的委託方法不火。很顯然,我的表格視圖沒有得到更新,查看新數據的唯一方法是顯式刷新或重新啓動應用程序。

我已經看過了CoreData食譜應用程序 - 但似乎無法找到我失蹤的東西。思考?

-Luther

+0

路德,你可以確認實體和謂詞你配置的NSFetchedResultsController? – ohhorob 2009-12-22 09:38:27

回答

3

如果我改變來自@「客戶」的sectionNameKeyPath到零,當我創建原始fetchedResultsController_,無論是Project實體創作保存確實調用委託方法!

fetchedResultsController_ = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:request 
             managedObjectContext:self.managedObjectContext 
              sectionNameKeyPath:nil 
                cacheName:@"ProjectsCache"]; 

經過高度審查,這就是CoreData Recipes示例所做的。隨着我的數據變得越來越複雜 - 我認爲我需要這個參數來幫助將結果分成幾個部分,但現在,很高興看到調用的委託處理程序。

1

我上面讀看起來像你正在使用2個NSManagedObjectContexts,一個在ProjectListViewController,並單獨一個在ProjectDetailViewController(我假設,因爲我沒有看到它在傳遞,但它創造了那裏。

當您保存一個上下文時,它不會自動將更改傳播到另一個上下文中,因此將其保存到ProjectDetailViewController中不會導致更改顯示在ProjectListViewController的上下文中,這意味着該更改沒有告訴委託人它

如果要推送上下文之間的更改,請查看NSManagedObjectContextDidSaveNotification和mergeChangesFromContextDidSaveNotification :(它們是NSManagedObjectContext的末尾documentation)。

+0

考慮到我看到的行爲,您的觀點確實有道理,是的,我已經能夠成功地使用通知來合併更改,但是,我無法理解是'爲什麼'這是必要的。我錯過了一些東西。 我使用相同的managedObjectContext來創建fetchedResultsController_,'newProject' 並且還保存'newProject'(上下文是從原始managedObjectContext創建的'newProject'的屬性)。 [self.project.managedObjectContext save:&error]; 我認爲委託方法應該在我創建AND時保存'newProject'時觸發。 – 2009-08-24 04:36:13