2013-01-16 31 views
0

我有一个NSFetchedResultsController,我已经确认他们是数据被保存到它,每当用户创建一个新的对象。但是,我发现唯一没有更新的东西仍然是NSFetchedResultsController的部分和行数。我不确定这是为什么。部分和行数NSFetchedResultsController

我试着用不同的方式创建新的对象。我也尝试记录过程中的每一步,试图看看发生了什么,但是我没有太多可以登录的东西,所以我现在几乎没有任何信息说明为什么会发生这种情况。不管怎么说,这里是代码:

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    NSLog(@"number of rows: %d", [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects]); 
    return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects]; 
} 

- (void)saveForName:(NSString *)name 
       photo:(NSData *)photo 
     timePosted:(NSDate *)timePosted 
      details:(NSString *)details 
     dateAndTime:(NSDate *)dateTime 
      location:(NSString *)location 
{ 

    if (!self.shindysDatabase) { 
     NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
     self.shindysDatabase = [[UIManagedDocument alloc] initWithFileURL:url]; 
     NSLog(@"shindy database reset."); 
    } 

    Shindy *shindy = (Shindy *)[NSEntityDescription insertNewObjectForEntityForName:@"Shindy" inManagedObjectContext:self.shindysDatabase.managedObjectContext]; 

    shindy.name = name; 
    shindy.photo = photo; 
    shindy.timePosted = timePosted; 
    shindy.details = details; 
    shindy.dateAndTime = dateTime; 
    shindy.location = location; 

    NSError *error = nil; 
    [self.shindysDatabase.managedObjectContext save:&error]; 
} 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 

    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; 
    } 

    Shindy *shindy = (Shindy *)[NSEntityDescription entityForName:@"Shindy" inManagedObjectContext:self.shindysDatabase.managedObjectContext]; 
    shindy = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

    UIImageView *avatar = [[UIImageView alloc] initWithFrame:CGRectMake(20, 10, 64, 56)]; 
    // Converting NSData to UIImage 
    avatar.image = shindy.photo; 
    avatar.clipsToBounds = NO; 
    [cell addSubview:avatar]; 

    NSLog(@"avatar: %@", avatar); 

    // The name of the user who posted the shindy 
    UILabel *avatarName = [[UILabel alloc] initWithFrame:CGRectMake(90, 10, 125, 19)]; 
    avatarName.font = [UIFont boldSystemFontOfSize:15]; 
    avatarName.backgroundColor= [UIColor clearColor]; 
    avatarName.text = shindy.name; 
    [cell addSubview:avatarName]; 

    NSLog(@"avatarName: %@", avatarName); 

    // The time the shindy was posted 
    NSDateFormatter *timePostedFormatter = [[NSDateFormatter alloc] init]; 
    [timePostedFormatter setDateFormat:@"mm"]; 
    UILabel *timePosted = [[UILabel alloc] initWithFrame:CGRectMake(280, 10, 30, 20)]; 
    timePosted.font = [UIFont systemFontOfSize:12]; 
    timePosted.textColor = [UIColor lightGrayColor]; 
    timePosted.backgroundColor= [UIColor clearColor]; 
    timePosted.text = [timePostedFormatter stringFromDate:shindy.timePosted]; 
    [cell addSubview:timePosted]; 

    NSLog(@"Time posted: %@", timePosted); 

    // Formatting fetched NSDate into string 
    NSDateFormatter *dateAndTimeFormatter = [[NSDateFormatter alloc] init]; 
    [timePostedFormatter setDateFormat:@"MM/DD/YYYY hh:mm"]; 
    UILabel *dateAndTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(250, 70, 30, 20)]; 
    dateAndTimeLabel.font = [UIFont systemFontOfSize:12]; 
    dateAndTimeLabel.backgroundColor= [UIColor clearColor]; 
    dateAndTimeLabel.text = [dateAndTimeFormatter stringFromDate:shindy.dateAndTime]; 
    [cell addSubview:dateAndTimeLabel]; 

    NSLog(@"date and time: %@", dateAndTimeLabel.text); 

    // Details of the Shindy 
    UILabel *shindyDescription = [[UILabel alloc] initWithFrame:CGRectMake(90, 20, 220 , 50)]; 
    shindyDescription.numberOfLines = 3; 
    shindyDescription.font = [UIFont systemFontOfSize:12]; 
    shindyDescription.backgroundColor = [UIColor clearColor]; 
    shindyDescription.text = shindy.details; 
    [cell addSubview:shindyDescription]; 

    NSLog(@"details: %@", shindyDescription.text); 

    return cell; 
} 

样板代码:

这只是我有当一个对象被改变做更新的代码。

- (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 { 

    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]; 
} 

回答

0

我没有在很长一段时间与NSFetchedResultController工作,但乍一看我会说:
Where are you asking your table view to update itself?
我不认为结果控制器将触发表更新本身。


我只是NSFetchedResultsController文档和我也看到了这一点:

此外,获取的成果控制器提供以下功能:
可选监测相关的管理对象的更改对象 上下文,并将结果中的更改报告给其代理(请参阅 “控制器的代表”)。

而且还NSFetchedResultsControllerDelegate文档

中,你可以只实现controllerDidChangeContent:(其被送到 时,所有待处理的更改已处理的代表)重新加载 表视图。


只是为了调试的目的,你有没有尝试删除:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath 
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 

而只是做:

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

我并不是说这是一个解决方案,但它看看结果是否相同会很有趣。

+0

我在其他地方已经在我的代码中设置了所有这些东西。该代码被认为是“默认”,所以我没有打扰发布。 – jakenberg

+0

您会惊讶地发现“默认”代码有多少错误 –

+0

它是从Apple文档复制并粘贴的。但我看到你真的想看到它,所以我编辑了我的问题,以显示它:) – jakenberg

0

您是否在创建NSFetchedResultsController对象时指定了sectionNameKeyPath?如果您使用nil,则只会创建一个部分。

(instancetype)initWithFetchRequest:(NSFetchRequest *)fetchRequest managedObjectContext:(的NSManagedObjectContext *)上下文sectionNameKeyPath:(的NSString *)sectionNameKeyPath cacheName:(的NSString *)名称;

sectionNameKeyPath: 返回段名称的结果对象上的键路径。通过零来表示控制器应该生成一个单独的部分。

相关问题