UITableView上的ContentDidChange带有节

UITableView上的ContentDidChange带有节,uitableview,core-data,Uitableview,Core Data,[注意,代码格式因复制和粘贴而变得怪异,特此致歉!] 嗨 我有一个tableview,它从核心数据中获取数据,并使用排序规则将数据写入表中以索引表。该代码稍微修改了Apple CoreDatabook中的代码 除非在核心数据中输入了新数据,然后我收到一条错误消息,上面写着下面的消息,否则一切正常。我见过其他一些网站有这个错误,但无法找到解决方案,我相信这与输入新数据之前的0行部分有关 ConnectU[6168:207]严重的应用程序错误。在调用-controllerDidChangeConte

[注意,代码格式因复制和粘贴而变得怪异,特此致歉!] 嗨

我有一个tableview,它从核心数据中获取数据,并使用排序规则将数据写入表中以索引表。该代码稍微修改了Apple CoreDatabook中的代码

除非在核心数据中输入了新数据,然后我收到一条错误消息,上面写着下面的消息,否则一切正常。我见过其他一些网站有这个错误,但无法找到解决方案,我相信这与输入新数据之前的0行部分有关

ConnectU[6168:207]严重的应用程序错误。在调用-controllerDidChangeContent:*期间,从NSFetchedResultsController的委托捕获到异常-[NSMUTABLEARRY objectAtIndex:]:索引0超出了具有userInfo(null)的空数组的界限

代码如下

@synthesize managedObjectContext=__managedObjectContext;
@synthesize fetchedResultsController;
@synthesize delegate;
@synthesize filteredListContent;
@synthesize savedSearchTerm;
@synthesize savedScopeButtonIndex;
@synthesize searchIsActive;
@synthesize friendDataArray, sectionsArray, collation;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {

        __managedObjectContext = [(ConnectUAppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext];

        self.title = @"Friends";

        UITabBarItem *item = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemContacts tag:0];
        self.tabBarItem = item; 
        [item release];

        NSError *error;
        if (![[self fetchedResultsController] performFetch:&error]) {
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        }

    }
    return self;
}

- (void)updateFeed:(id)sender {
    // Add some new data to the core data and save, no problems  

    [self.tableView reloadData];  
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Set the table view's row height
    self.tableView.rowHeight = 44.0;

    //Add the refresh button
    UIBarButtonItem* refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(updateFeed:)];
    [self.navigationItem setLeftBarButtonItem:refreshButton animated:YES];
    [refreshButton release]; 


    // ******** Search Bar Set Up ******** //
    // hidden to reduce code here
    // ******** Search Bar Set Up Complete ******** //

    // Get the friends data
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:[NSEntityDescription entityForName:@"Friends" inManagedObjectContext:[self managedObjectContext]]];

    NSError *error2 = nil;
    NSArray *fetchResults2 = [[self managedObjectContext] executeFetchRequest:request error:&error2];

    if (fetchResults2) {
        friendDataArray = [NSMutableArray arrayWithArray:fetchResults2];    
    }

    [self configureSections];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    if (self.searchIsActive) {
        return 1;
    }

        // The number of sections is the same as the number of titles in the collation.
    return [[collation sectionTitles] count];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    // If a search is taking place, return number of items in filteredListContent
    if (self.searchIsActive) {
        return [self.filteredListContent count];
    }

        // The number of time zones in the section is the count of the array associated with the section in the sections array.
        NSArray *timeZonesInSection = [sectionsArray objectAtIndex:section];

    return [timeZonesInSection count];
}



- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    NSArray *friendsInSection = [sectionsArray objectAtIndex:section];
    if( [friendsInSection count] != 0 ) {
        return [[collation sectionTitles] objectAtIndex:section];
    }

    return @"";
}


- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [collation sectionIndexTitles];
}


- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return [collation sectionForSectionIndexTitleAtIndex:index];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Friends_View";

    // Create a cell, reuse a useable cell if available
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell
        [self configureCell:cell atIndexPath:indexPath];
    return cell;

}


- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath   {

    // If search is taking place, then get cell contents from the filteredlistcontent
    if (self.searchIsActive) {

        Friends *friend = [[self filteredListContent] objectAtIndex:[indexPath row]];
        NSString *name = [[NSString alloc] initWithFormat:@"%@ %@", [friend valueForKeyPath:@"first_name"] ,[friend valueForKeyPath:@"last_name"]];
        cell.textLabel.text = name;
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    // No search taking place so therefore get data from sectionsArray
    } else {

        // Get the time zone from the array associated with the section index in the sections array.
        NSArray *friendsInSection = [sectionsArray objectAtIndex:indexPath.section];

        // Configure the cell with the time zone's name.
        Friends *friend = [friendsInSection objectAtIndex:indexPath.row];


        NSString *name = [[NSString alloc] initWithFormat:@"%@ %@", [friend valueForKeyPath:@"first_name"] ,[friend valueForKeyPath:@"last_name"]];
        cell.textLabel.text = name;
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
}


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

    // If search is taking place, get object from filteredListContent
    if (self.searchIsActive) {
        friend = [[self filteredListContent] objectAtIndex:[indexPath row]];

    // Else get a normal friend object
    } else {
        NSArray *friendsInSection = [sectionsArray objectAtIndex:indexPath.section];
        friend = [friendsInSection objectAtIndex:indexPath.row];
    }

    // Create a friendDetail View controller and push this into the view
    FriendsDetail_ViewController *friendsDetail = [[FriendsDetail_ViewController alloc] initWithStyle:UITableViewStyleGrouped];

    NSString *name = [[NSString alloc] initWithFormat:@"%@ %@", [friend valueForKeyPath:@"first_name"] ,[friend valueForKeyPath:@"last_name"]];
    friendsDetail.title = name;
    friendsDetail.friend_data = friend;
    [friendsDetail setDelegate:self];
    [self.navigationController pushViewController:friendsDetail animated:YES];

    [friendsDetail release];

}


- (void)configureSections {

        // Get the current collation and keep a reference to it.
        self.collation = [UILocalizedIndexedCollation currentCollation];

        NSInteger index, sectionTitlesCount = [[collation sectionTitles] count];

        NSMutableArray *newSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];

        // Set up the sections array: elements are mutable arrays that will contain the time zones for that section.
        for (index = 0; index < sectionTitlesCount; index++) {
                NSMutableArray *array = [[NSMutableArray alloc] init];
                [newSectionsArray addObject:array];
                [array release];
        }

        // Segregate the time zones into the appropriate arrays.
        for (Friends *friend in friendDataArray) {

                // Ask the collation which section number the time zone belongs in, based on its locale name.
                NSInteger sectionNumber = [collation sectionForObject:friend collationStringSelector:@selector(first_name)];

                // Get the array for the section.
                NSMutableArray *sectionTimeZones = [newSectionsArray objectAtIndex:sectionNumber];

                //  Add the time zone to the section.
                [sectionTimeZones addObject:friend];
        }

        // Now that all the data's in place, each section array needs to be sorted.
        for (index = 0; index < sectionTitlesCount; index++) {

                NSMutableArray *timeZonesArrayForSection = [newSectionsArray objectAtIndex:index];

                // If the table view or its contents were editable, you would make a mutable copy here.
                NSArray *sortedTimeZonesArrayForSection = [collation sortedArrayFromArray:timeZonesArrayForSection collationStringSelector:@selector(first_name)];

                // Replace the existing array with the sorted array.
                [newSectionsArray replaceObjectAtIndex:index withObject:sortedTimeZonesArrayForSection];
        }

        self.sectionsArray = newSectionsArray;
        [newSectionsArray release]; 
}


- (NSFetchedResultsController *)fetchedResultsController {

    // Set up the fetched results controller if needed.
    if (fetchedResultsController == nil) {
        // Create the fetch request for the entity.
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        // Edit the entity name as appropriate.
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Friends" inManagedObjectContext:[self managedObjectContext]];
        [fetchRequest setEntity:entity];

        // Edit the sort key as appropriate.
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"first_name" ascending:YES selector:nil];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

        // Recover query


        [fetchRequest setSortDescriptors:sortDescriptors];

        // Edit the section name key path and cache name if appropriate.
        // nil for section name key path means "no sections".
        NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];
        aFetchedResultsController.delegate = self;
        self.fetchedResultsController = aFetchedResultsController;

        [aFetchedResultsController release];
        [fetchRequest release];
        [sortDescriptor release];
        [sortDescriptors release];

    }

        return fetchedResultsController;
}




- (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 <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];
}
@synthesis managedObjectContext=\uu managedObjectContext;
@合成取数结果控制器;
@综合代表;
@合成过滤膜;
@合成保存的搜索项;
@合成savedScopeButtonIndex;
@综合搜索活跃;
@综合friendDataArray、sectionsArray、校对;
-(id)initWithStyle:(UITableViewStyle)样式
{
self=[super initWithStyle:style];
如果(自我){
__managedObjectContext=[(ConnectUAppDelegate*)[UIApplication sharedApplication]。委托managedObjectContext];
self.title=@“朋友”;
UITabBarItem*项=[[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemContacts标记:0];
self.tabBarItem=项目;
[项目发布];
n错误*错误;
如果(![[self-fetchedResultsController]性能检测:&错误]){
//更新以适当地处理错误。
NSLog(@“未解决的错误%@,%@”,错误,[error userInfo]);
退出(-1);//失败
}
}
回归自我;
}
-(void)updateFeed:(id)发送者{
//向核心数据添加一些新数据并保存,没有问题
[self.tableView重载数据];
}
-(无效)viewDidLoad
{
[超级视图下载];
//设置表视图的行高度
self.tableView.rowHeight=44.0;
//添加刷新按钮
UIBarButtonItem*refreshButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarbuttonSystemRefresh目标:自我操作:@selector(updateFeed:)];
[self.navigationItem setLeftBarButtonItem:refreshButton动画:是];
[刷新按钮释放];
//*******搜索栏设置*******//
//隐藏以减少代码
//*******搜索栏设置完成*******//
//获取好友数据
NSFetchRequest*request=[[NSFetchRequest alloc]init];
[request setEntity:[NSEntityDescription entityForName:@“Friends”inManagedObjectContext:[self-managedObjectContext]];
N错误*错误2=零;
NSArray*fetchResults2=[[self-managedObjectContext]executeFetchRequest:请求错误:&error2];
if(fetchResults2){
friendDataArray=[NSMutableArray arrayWithArray:fetchResults2];
}
[自我配置部分];
}
-(NSInteger)表格视图中的节数:(UITableView*)表格视图{
如果(self.searchIsActive){
返回1;
}
//节数与排序规则中的标题数相同。
返回[[排序规则节标题]计数];
}
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节{
//如果正在进行搜索,则返回filteredListContent中的项目数
如果(self.searchIsActive){
返回[self.filteredListContent count];
}
//节中的时区数是与节数组中的节关联的数组计数。
NSArray*TimeZoneInsection=[sectionsArray对象索引:section];
返回[TimeZoneInsection计数];
}
-(NSString*)表格视图:(UITableView*)表格视图标题标题标题部分:(NSInteger)部分{
NSArray*friendsInSection=[sectionsArray对象索引:section];
如果([friendsInSection count]!=0){
返回[[排序规则节标题]对象索引:节];
}
返回@”;
}
-(NSArray*)sectionIndexTitlesForTableView:(UITableView*)表格视图{
返回[排序规则节索引];
}
-(NSInteger)tableView:(UITableView*)分区索引的tableView部分exttitle:(NSString*)标题索引:(NSInteger)索引{
返回[排序规则部分ForSectionIndexTitleAtIndex:index];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
静态NSString*CellIdentifier=@“好友视图”;
//创建单元格,重用可用单元格(如果可用)
UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
如果(单元格==nil){
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault重用标识符:CellIdentifier]自动释放];
}
//配置单元格
[self-configureCell:cell-atIndexPath:indexPath];
返回单元;
}
-(void)configureCell:(UITableViewCell*)单元格atIndexPath:(NSIndexPath*)indexPath{
//如果正在进行搜索,则从filteredlistcontent获取单元格内容
如果(self.searchIsActive){
Friends*friend=[[self-filteredListContent]objectAtIndex:[indexPath行]];
NSString*name=[[NSString alloc]initWithFormat:@“%@%@”,[friend valueForKeyPath:@“first_name”],[friend valueForKeyPath:@“last_name”];
cell.textlab.text=名称;
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
//没有进行搜索,因此从sectionsArray获取数据
}否则{
//从与sections数组中的节索引关联的数组中获取时区。
NSArray*friendsInSection=[sectionsArray对象索引:indexath.section];
//使用时区名称配置单元格。
Friends*friend=[friendsInSection对象索引:indexath.row];