UITableView停止加载IOS7和Xcode5中的数据

问题描述:

我有一个简单的视图,在过去的18个月里,它已成功地从CoreData中加载数据表。它现在甚至可以在已升级到IOS 7的设备上运行。但是,当我升级到Xcode5并通过IOS7 3.5英寸视网膜模拟器运行时,我的表总是空的。我在下面粘贴了我的代码,我可以确认fetchRequests正在返回数据,因为我可以在NSLog输出中看到它。但为什么桌子停止填充单元格?UITableView停止加载IOS7和Xcode5中的数据

我觉得很愚蠢,因为我实在不明白这一个...

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
     NSLog(@"listData count in numberOFRowsInSection is: %i", listData.count); 
     return [self.listData count]; 
    } 

    - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { 
     Sessions *info = [_fetchedResultsController objectAtIndexPath:indexPath]; 
     NSLog(@"info content is: %@", info.sport); 
     //Format cell data ready to be displayed 
     NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
     [dateFormat setDateFormat:@"EE, dd LLL yyyy"]; 
     NSString *dateString = [dateFormat stringFromDate:info.date]; 

     NSNumber *dist1Nbr = info.dist1; 
     int dist1Int = [dist1Nbr integerValue]; 
     float distIntKorM = ([dist1Nbr integerValue])/1000; 
     NSString *dist1StrMeters = [[NSString alloc] initWithFormat:@"%i", dist1Int]; 
     NSString *dist1StrKorM = [[NSString alloc] initWithFormat:@"%.01f", distIntKorM]; 


     //Select image to display 
     if ([info.sport isEqualToString:@"Run"]) { 
      UIImage *image = [UIImage imageNamed:@"trainers-15x10.png"]; 
      cell.imageView.image = image; 
      cell.textLabel.text = [[NSString alloc] initWithFormat:@"%@: (%@),", dateString, info.sport]; 
      cell.detailTextLabel.text = [[NSString alloc] initWithFormat:@"Type: %@, Dist: %@", info.sessiontype, dist1StrKorM]; 
      NSLog(@"Cell text for Runs shoudl be: %@", cell.textLabel.text); 
     } else if ([info.sport isEqualToString:@"Other"]) { 
      UIImage *image = [UIImage imageNamed:@"weights-15x10.png"]; 
      cell.imageView.image = image; 
      cell.textLabel.text = [[NSString alloc] initWithFormat:@"%@: (%@),", dateString, info.sport]; 
      cell.detailTextLabel.text = [[NSString alloc] initWithFormat:@"Type: %@, Dist: %@", info.sessiontype, dist1StrKorM]; 
     } else if ([info.sport isEqualToString:@"Swim"]) { 
      UIImage *image = [UIImage imageNamed:@"goggles-15x10.png"]; 
      cell.imageView.image = image; 
      cell.textLabel.text = [[NSString alloc] initWithFormat:@"%@: (%@),", dateString, info.sport]; 
      cell.detailTextLabel.text = [[NSString alloc] initWithFormat:@"Type: %@, Dist: %@m", info.sessiontype, dist1StrMeters]; 
      NSLog(@"Cell text for Swims shoudl be: %@", cell.textLabel.text); 
     } else if ([info.sport isEqualToString:@"Cycle"]) { 
      UIImage *image = [UIImage imageNamed:@"bike-15x10.png"]; 
      cell.imageView.image = image; 
      cell.textLabel.text = [[NSString alloc] initWithFormat:@"%@: (%@),", dateString, info.sport]; 
      cell.detailTextLabel.text = [[NSString alloc] initWithFormat:@"Type: %@, Dist: %@", info.sessiontype, dist1StrKorM]; 
     } else if ([info.sport isEqualToString:@"Brick"]) { 
      UIImage *image = [UIImage imageNamed:@"brick-15x10.png"]; 
      cell.imageView.image = image; 
      cell.textLabel.text = [[NSString alloc] initWithFormat:@"%@: (%@),", dateString, info.sport]; 
      cell.detailTextLabel.text = [[NSString alloc] initWithFormat:@"Type: %@, Dist: %@", info.sessiontype, dist1StrKorM]; 
     } 

    } 

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

     static NSString *CellIdentifier = @"editSession"; 

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 

      } 
      // this cell backgrond colour alternating works! 
      UIView *bgColor = [cell viewWithTag:100]; 
      if (!bgColor) { 
       CGRect frame = CGRectMake(0, 0, 320, 50); 
       bgColor = [[UIView alloc] initWithFrame:frame]; 
       bgColor.tag = 100; 
       [cell addSubview:bgColor]; 
       [cell sendSubviewToBack:bgColor]; 
      } 

      if (indexPath.row % 2 == 0) { 
       bgColor.backgroundColor = [UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:1.0]; 
        } else { 
         bgColor.backgroundColor = [UIColor clearColor];        } 

     [self configureCell:cell atIndexPath:indexPath]; 

     return cell; 
    } 


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


    - (void)didReceiveMemoryWarning 
    { 
     // Releases the view if it doesn't have a superview. 
     [super didReceiveMemoryWarning]; 

     // Release any cached data, images, etc that aren't in use. 
    } 

    #pragma mark - View lifecycle 

    - (void)viewDidLoad 
    { 
     [super viewDidLoad]; 

     // Uncomment the following line to preserve selection between presentations. 
     // self.clearsSelectionOnViewWillAppear = NO; 

     // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 
     // self.navigationItem.rightBarButtonItem = self.editButtonItem; 
     if (_context == nil) 
     { 
      _context = [(SGK_T4T_01AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
      NSLog(@"After managedObjectContext: %@", _context); 
     } 

     NSError *error; 
     if (![[self fetchedResultsController] performFetch:&error]) { 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      exit(-1); 
     } else { 
      NSLog(@"After fetchedResultsController: %@", _fetchedResultsController); 
      //NSLog(@"After managedObjectContext: %@", _fetchedResultsController); 
     } 
     self.title = @"Sessions"; 


    } 

    - (void)viewDidUnload 
    { 
     [super viewDidUnload]; 
     // Release any retained subviews of the main view. 
     // e.g. self.myOutlet = nil; 

     [self setListData:nil]; 
     [self setSelectedSession:nil]; 
     [self setSessionSport:nil]; 
     //[self setRecordCount:nil]; 
     [self setFetchedResultsController:nil]; 
     [self setContext:nil]; 
    } 

    - (void)viewWillAppear:(BOOL)animated 
    { 
     [super viewWillAppear:animated]; 

     SGK_T4T_01AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 
     NSManagedObjectContext *context = [appDelegate managedObjectContext]; 
     NSEntityDescription *entityDiscription = [NSEntityDescription entityForName:@"Sessions" inManagedObjectContext:context]; 
     //NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"refid" ascending:YES]; 
     NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
     [request setEntity:entityDiscription]; 


     NSError *error; 
     NSArray *objects = [context executeFetchRequest:request error:&error]; 
     if (objects == nil) { 

      NSLog(@"The fetch request returned an array == nil"); 
     } else { 
      NSLog(@"The fetch request returned an array!!!"); 
      NSLog(@"objects contents is: %@", objects); 
      NSLog(@"objects count = %i", [objects count]); 
      listData = objects; 
      NSLog(@"listData count = %i", [listData count]); 
      //NSUInteger *recordCount = [objects count]; 
      recordCount = [objects count]; 
     } 

     //reload tableView:dataSource from CoreData when view reappears... 
     if (_context == nil) 
     { 
      _context = [(SGK_T4T_01AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
      NSLog(@"After managedObjectContext: %@", _context); 
     } 

     NSError *error1; 
     if (![[self fetchedResultsController] performFetch:&error1]) { 
      NSLog(@"Unresolved error %@, %@", error1, [error1 userInfo]); 
      exit(-1); 
     } else { 
      NSLog(@"viewWillAppear: fetchedResultsController: %@", _fetchedResultsController); 
     } 
     //end of reload tableView:dataSource from CoreData when view reappears... 

     [self.tableView reloadData]; 
    } 

    - (void)viewDidAppear:(BOOL)animated 
    { 
     [super viewDidAppear:animated]; 

    } 

    - (void)viewWillDisappear:(BOOL)animated 
    { 
     [super viewWillDisappear:animated]; 
     //[self setFetchedResultsController:nil]; 
    } 

    - (void)viewDidDisappear:(BOOL)animated 
    { 
     [super viewDidDisappear:animated]; 
     //[self setFetchedResultsController:nil]; 
    } 

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
    { 
     // Return YES for supported orientations 
     return (interfaceOrientation == UIInterfaceOrientationPortrait); 
    } 

    #pragma mark - Table view data source 

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    { 
    //#warning Potentially incomplete method implementation. 
     // Return the number of sections. 
     return 1; 
    } 

    /* 
    // Override to support conditional editing of the table view. 
    - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     // Return NO if you do not want the specified item to be editable. 
     return YES; 
    } 
    */ 


    // Override to support editing the table view. 
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     if (editingStyle == UITableViewCellEditingStyleDelete) { 
      // Delete the row from the data source 
      [_context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 

      NSError *error = nil; 
      if (![_context save:&error]) { 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
       } 
      } else if (editingStyle == UITableViewCellEditingStyleInsert) { 
      // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 
     } 
     [self.tableView reloadData]; 
    } 

    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath 
    { 
     if (type == NSFetchedResultsChangeDelete) { 
      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     } 
    } 

    #pragma mark - Table view delegate 

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    { 

    } 

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
     NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; 
     NSUInteger index = indexPath.row; 
     //NSLog(@" Prep4Seg indexPath.row = %u", index); 
     //NSLog(@" Prep4Seg recordCount = %u", recordCount); 
     /* 
      Subtract the row index from the row count to get the correct position in the Array (because I am sorting on date order so tableCell position 0 is position 2 in the Array (if there are 3 only items in the table and array) so if you don't invert the indexPath you end up passing the last item instead of the first or second last item instead of the second and so on... 
     */ 
     NSUInteger arrayIndex = (recordCount-index-1); 
     //NSLog(@" Prep4Seg arrayIndex = %u", arrayIndex); 
     selectedSession = [listData objectAtIndex:arrayIndex]; 
     //NSLog(@"listData = %@", listData); 
     //NSLog(@"SelectedSession = %@", selectedSession); 

     NSNumber *refId = [selectedSession valueForKey:@"refid"]; 
     NSString *refIdToSend = [[NSString alloc] initWithFormat:@"%@", refId]; 
     NSLog(@"Prep4Seg in tableView: refIdToSend = %@", refIdToSend); 

     if ([segue.identifier isEqualToString:@"editSession"]) { 
      SGK_T4T_EditSessionDetail *editSessionDetail = segue.destinationViewController; 
      editSessionDetail.delegate = (id)self; 
      editSessionDetail.returnFromDatePickerView = [[NSString alloc] initWithFormat:@"no"]; 
      editSessionDetail.recedIndex = refIdToSend; 
     } 
    } 

    - (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 didChangeSection:(id <NSFetchedResultsSectionInfo>)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]; 
    } 

我的日志输出是:

2013-11-09 16:04:04.034 trainForTri copy[6509:a0b] After managedObjectContext: <NSManagedObjectContext: 0xb589bc0> 
2013-11-09 16:04:04.036 trainForTri copy[6509:a0b] After fetchedResultsController: <NSFetchedResultsController: 0xb5e2c40> 
2013-11-09 16:04:04.040 trainForTri copy[6509:a0b] The fetch request returned an array!!! 
2013-11-09 16:04:04.041 trainForTri copy[6509:a0b] objects contents is: (
    "<NSManagedObject: 0xb5c8570> (entity: Sessions; id: 0xb5ac970 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p1> ; data: <fault>)", 
    "<NSManagedObject: 0xb5d6320> (entity: Sessions; id: 0xb58a2a0 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p2> ; data: <fault>)", 
    "<NSManagedObject: 0xb5d0370> (entity: Sessions; id: 0xb5dc270 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p3> ; data: <fault>)", 
    "<NSManagedObject: 0xb5e3dd0> (entity: Sessions; id: 0xb5ebcc0 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p4> ; data: <fault>)", 
    "<NSManagedObject: 0xb585e40> (entity: Sessions; id: 0xb5e4e40 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p5> ; data: <fault>)" 
) 
2013-11-09 16:04:04.041 trainForTri copy[6509:a0b] objects count = 5 
2013-11-09 16:04:04.042 trainForTri copy[6509:a0b] listData count = 5 
2013-11-09 16:04:04.043 trainForTri copy[6509:a0b] viewWillAppear: fetchedResultsController: <NSFetchedResultsController: 0xb5a01e0> 
2013-11-09 16:04:04.043 trainForTri copy[6509:a0b] listData count in numberOFRowsInSection is: 5 
+0

是否调用了“cellForRowAtIndexPath”?此外,你打印'listData.count'并返回'[self.listData count]'...你确定那些是相同的东西吗? (财产与变量?) –

+1

我打赌@PhillipMills是正确的。你已经显式创建了一个'listData'伊娃,并没有'@synthesize listData',所以它使用了一个隐含的'_listData'属性。这只是你应该总是使用'.property'并避免直接ivars **的另一个原因。 – Kevin

+0

@PhillipMills和谢谢你的意见。我做综合listData,即使我改变它{return [listData count];}它没有区别。我已经通过在cellForRowAtIndexPath中放置一个NSLog进行了测试,但是我没有得到输出 - 所以我猜测它没有被调用 - 但为什么在Xcode5之前总是这样做。任何进一步的想法,因为我很难过! – Sean

OK,发现问题与此有关。最终在Xcode5沮丧地想把我的Macbook扔出窗外之后,我关闭了所有东西并重新启动。当我打开Xcode,构建并运行我的应用程序时,它更长的时间加载了一个空表 - 它现在产生了一个错误,表明我的NSFetchedResultsController出了问题。我将其追踪到缓存未清除(或不可变)的问题 - 因此我删除了缓存名称并将其设置为零,并且所有内容都再次运行。我不确定这是否是IOS7/Xcode5问题,但在升级之前它一直没有问题。对于任何寻找类似修复程序的人来说,这里是违规的代码行:

NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:@"Root"]; 

而这是工作的版本!

NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:nil]; 

我希望我不是唯一一个与此斗争,因此只是一个厚厚的!