2011-10-20 32 views
12

Uygulamamın içinde yeni yönetilen nesneler oluşturabilirim, ayrı bir görünümde Sahip olduğum tüm nesneleri gösteren bir tablo görünümüne sahibim.NSFetchedResultsController verilerini yenile?

Yeni yönetilen bir nesne oluşturduğumda (tamamen ayrı bir görünümde), tablo görünümümü yeni oluşturduğum yeni nesneyi içeren yeni verilerle yeniden yüklemeye çalışan bir bildirim gönderiyorum.

Tablo görünümünü düzenlemiyorum.

Sadece bir yönetilen içerik var.

Neyi yanlış yaptığımı anlayamıyorum. Uygulamayı kapatırsam ve yeni nesneyi yeniden başlatırsam tablo görünümünde olur. Yeni bir nesne yapıldıktan sonra bildirimi aldığımda reloadData'yi aramaya çalışıyorum ve tekrar getirmeyi de denedim, ancak sonuçta boş bir tablo görünümündeyim.

kod açısından

, benim ListViewController:

@interface MyNotesViewController : UIViewController 
{ 
    NSManagedObjectContext * __managedObjectContext; 
    UITableView * _notesTableView; 
    MyNotesTableViewDelegate_DataSource * _tableDelegate_DataSource; 
} 

Benim viewDidLoad şuna benzer: Benim temsilci/veri kaynağı nesnesinde

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _tableDelegate_DataSource = [[MyNotesTableViewDelegate_DataSource alloc] init]; 
    _tableDelegate_DataSource.managedObjectContext = __managedObjectContext; 
    [_notesTableView setDataSource:_tableDelegate_DataSource]; 

    NSError * _coreDataError; 
    BOOL success = [[_tableDelegate_DataSource fetchedResultsController] performFetch:&_coreDataError]; 

    if(success){ 
     [_notesTableView reloadData]; 
    } 
} 

Ben:

@interface MyCommutesTableViewDelegate_DataSource : NSObject 

<UITableViewDataSource, NSFetchedResultsControllerDelegate> 
{ 
    NSManagedObjectContext * __managedObjectContext; 
    NSFetchedResultsController * __fetchedResultsController; 
} 

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; 

@end 

Uygulama alıntı :

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    id <NSFetchedResultsSectionInfo> sectionInfo = 
    [[__fetchedResultsController sections] objectAtIndex:section]; 
    return [sectionInfo numberOfObjects]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"NotesTableViewCell"; 

    NotesTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) {   
     NSArray * topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NotesTableViewCell" owner:nil options:nil]; 
     for(id currentObject in topLevelObjects){ 
      if([currentObject isKindOfClass:[UITableViewCell class]]){ 
       cell = (NotesTableViewCell*) currentObject; 
       break; 
      } 
     } 

    } 

// Configure the cell. 
    Note * _note = [__fetchedResultsController objectAtIndexPath:indexPath]; 

    [...] 

    return cell; 
} 

GÜNCELLEME

Ben hızlı düzeltme sorunum vardı çünkü sadece tüm nesneleri istemeden geri verildi ve sonra fark ettim, sonra:

-(NSFetchedResultsController*)fetchedResultsController{ 
    if(!__fetchedResultsController){ 
     NSFetchRequest * request = [[NSFetchRequest alloc] init]; 
     [request setEntity:[NSEntityDescription entityForName:@"Note" inManagedObjectContext:__managedObjectContext]]; 

     [request setFetchBatchSize:10]; 

     NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"noteDate" ascending:NO]; 
     [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
     [sortDescriptor release]; 

     __fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:__managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 


     __fetchedResultsController.delegate = self; 
     [request release]; 

    } 
    return __fetchedResultsController; 
} 

Burada stander UITableView veri kaynağı yöntemleri var İçeriğimi koruyorum, daha önce uygulama lansmanında kullandım alma isteğim, şimdi hiç veri göndermiyor, hata yok ama sadece hiçbir şey döndüremiyor.

Yani, NSFetchResultsController'ı nasıl uyguladığımla ilgili bir sorun yok. Ancak, yeni bir nesneyi kaydettikten sonra istekleri nasıl iade etmeyecek?

Not Yeni eklenenler de dahil olmak üzere, yeniden başlattığımda hala tüm nesnelerimi alıyorum.

standart isteği: Bana Çekirdek Veri eklenmiş yeni bir nesne anlatan bir bildirim bekliyorum, sonra yukarıdaki yöntemini çağırarak sonra benim tableview üzerinde reloadData arıyorum

-(NSArray*)getNotes{ 
    NSFetchRequest * request = [[NSFetchRequest alloc] init]; 

    NSEntityDescription * entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:[self managedObjectContext]]; 
    [request setEntity:entity]; 

    NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"noteDate" ascending:NO]; 
    [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
    [sortDescriptor release]; 

    NSError * coreDataError; 
    NSArray * fetchedObjects = [[self managedObjectContext] executeFetchRequest:request error:&coreDataError]; 
    [request release]; 

    if(fetchedObjects != nil){ 
     return fetchedObjects; 
    } else { 
     NSLog(@"ERR: %@", coreDataError); 
     return nil; 
    } 
} 

...

cevap

26

UITableViewController ayarlarınızı NSFetchedResultsControllerDelegate olarak ayarlıyorsunuz. Bu iyi. Şimdi şöyle TableViewController içinde controllerDidChangeContent: yöntemini uygulamaya çalışıyorum:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView reloadData]; 
} 

Sizin NSFetchedResultsController Çekirdek veri kaldırılan veya yeni nesnelere dinlemek ve değişikliklerin onun temsilci (sizin TableViewController) bildirecektir. Bunu, UITableView'daki ekleme ve kaldırma animasyonları ile daha da iyi uygulamak için Xcode'ta Çekirdek Veri şablonu projesini kontrol edin.

+0

uygulamak. – huesforalice

+10

Ayrıca, 'NSFetchedResultsController' sadece '-save:' 'NSManagedObjectContext' üzerinde çağrılan '' tepki vereceğini unutmayın. Bu nedenle, yeni oluşturulan varlığı kaydetmiyorsanız bu yöntemi ateşlemeyebilirsiniz. –

+0

Teşekkürler, controllerDidChangeContent uygulamıyorum: NSFetchedResultsControllerDelegate protokolünden, reloadData'yu masaüstümde çağırıyorum. Kesme noktaları ekledim ve bu yöntem çağrılıyor, ancak tablo görünümü boş yeniden yükleniyor. Uygulamayı yeniden başlatırsam yeni kayıtları da içeren tüm kayıtlarımı görebilirim. Neyi kaçırıyorum? Not: Denetleyiciyi uygulamak zorunda mıyım? DidChangeObject: atIndexPath: forChangeType: newIndexPath? – Daniel

2

didChangeObject yöntemi eklemek için emin olun:

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id) anObject 
     atIndexPath:(NSIndexPath *)indexPath 
    forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    switch(type) 
    { 
    case NSFetchedResultsChangeInsert: 
     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    case NSFetchedResultsChangeDelete: 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    case NSFetchedResultsChangeUpdate: 
     [self configureCell:[self.tableView 
    cellForRowAtIndexPath:indexPath] 
       atIndexPath:indexPath]; 
     break; 
    case NSFetchedResultsChangeMove: 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     [self.tableView insertRowsAtIndexPaths:[NSArray 
          arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    } 
} 

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 
    NSManagedObject *note = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    cell.textLabel.text = [note valueForKey:@"title"]; 
} 

yeni yönetilen nesne bundan sonra tablo görünümünde ortaya çıktı. Sadece bunu olduğu gibi, aynı sorunu olan vaka birisi olarak

0

. Yukarıdaki çözümü yeşil kene ile denedim, ama benim için işe yaramayacaktı. Apple's code'u takip ettim ve her şey yolunda gitti.

basitçe, sadece üç "Fetchcontroller" temsilci fonksiyonları size durumunda _notesTableView yeniden isteyeceksiniz elbette

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
      self.tableView.beginUpdates() 
     } 


    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 

      switch type { 
      case .Insert: 
       self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade) 
      case .Delete: 
       self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) 
      case .Update: 
       print("") 
       self.configureCell(self.tableView.cellForRowAtIndexPath(indexPath!)!, indexPath: indexPath!) 
      case .Move: 
       self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) 
       self.tableView.insertRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) 
      } 
     } 


func controllerDidChangeContent(controller: NSFetchedResultsController) { 
      self.tableView.endUpdates() 
     }