在表视图上获取EXC_BAD_ACCESS

时间:2013-08-01 07:49:02

标签: ios objective-c out-of-memory

我正在尝试在Xcode上做联系人应用程序,联系人列表显示但是当我点击任何名称时它会抛出错误EXC_BAD_ACCESS,我已经检查过NSLog并发现我的数组在填充tableview时出错了,这是我的代码:

//数组初始化为

@property (strong,nonatomic) NSMutableArray *filteredData,*contactAdd;

//在此函数上填充的数组

-(void)reloadAddressBook
{
    self.contactAdd = [[NSMutableArray alloc]init];    
    ABAddressBookRef addressBook = ABAddressBookCreate();//ABAddressBookCreateWithOptions(NULL,NULL);
    if(ABAddressBookHasUnsavedChanges(addressBook))
    {

        ABAddressBookSave(addressBook,NULL);
    }

    NSMutableArray *allPeople = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
    int nPeople = ABAddressBookGetPersonCount(addressBook);

    for(int i=0; i < nPeople; i++ )
    {
        ABRecordRef person = (__bridge ABRecordRef)([allPeople objectAtIndex:i]);

        [self.contactAdd addObject:(__bridge id)(person)];

        NSLog(@"@details %@",contactAdd);
        CFRelease(person);
    }
    CFRelease(addressBook);
}

//此函数出错

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
                   static NSString *cellIdentifier;


            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];


            if (cell == nil)
                {
                    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
               }

            if(isFiltered)
            {
               ABRecordRef person = (__bridge ABRecordRef)[self.filteredData objectAtIndex:indexPath.row];
                NSString *tweet=[[NSString stringWithFormat:@"%@", ABRecordCopyValue(person, kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                [cell.textLabel setText:tweet];
                CFRelease(person);

            }
            else
            {
                ABRecordRef person = (__bridge ABRecordRef)([self.contactAdd objectAtIndex:indexPath.row]);
                NSLog(@"%@",person);
                NSString *tweet=[[NSString stringWithFormat:@"%@", ABRecordCopyValue(person, kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                [cell.textLabel setText:tweet];
                CFRelease(person);
                NSLog(@"%@",indexPath);
// I have 4 contacts currently and error occurs here on 4th time and when I continue error occurs on 2nd time
                NSLog(@"@details %@",contactAdd); 
}
return cell;
}

//在运行时获取错误

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ABPersonViewController *currentPersonView=[[ABPersonViewController alloc]init];

    ABRecordRef person;
    if(isFiltered)
        person=(__bridge ABRecordRef)([self.filteredData objectAtIndex:indexPath.row]);
    else
        person=(__bridge ABRecordRef)([self.contactAdd objectAtIndex:indexPath.row]);//error here

    currentPersonView.displayedPerson=person;
    currentPersonView.allowsEditing=YES;
    currentPersonView.allowsActions=YES;
    [self.navigationController pushViewController:currentPersonView animated:YES];

}

// NSLog的

2013-08-01 13:11:12.715联系人[7722:207] 2个索引[0,0]

当前语言:auto;目前客观的c 2013-08-01 13:11:26.614联系人[7722:207] @details(     “CPRecord:0xba1b340 ABPerson”,     “CPRecord:0xba1c870 ABPerson”,     “CPRecord:0xba1c160 ABPerson”,     “CPRecord:0xba1c990 ABPerson” )

2013-08-01 13:11:26.616联系人[7722:207]

2013-08-01 13:11:26.617联系人[7722:207] 2个索引[0,1]

2013-08-01 13:11:27.566联系人[7722:207] @details(     “CPRecord:0xba1b340 ABPerson”,     “CPRecord:0xba1c870 ABPerson”,     “CPRecord:0xba1c160 ABPerson”,     “CPRecord:0xba1c990 ABPerson” ) 2013-08-01 13:11:27.567联系人[7722:207] 2013-08-01 13:11:27.568联系人[7722:207] 2个索引[0,2] (gdb)

4 个答案:

答案 0 :(得分:0)

首先为您的cellIdentifier添加一个值:

static NSString *cellIdentifier = @"CellIdentifie R“;

答案 1 :(得分:0)

不要让static NSString *cellIdentifier;没有值,例如:

static NSString *cellIdentifier = @"SimpleTableCell"

cellIdentifier添加到.m文件后,请确保在故事板中为tableView单元格添加了一个

查看此图片:http://www.appcoda.com/wp-content/uploads/2012/04/SimpleTable-Cell-Identifier.jpg

(抱歉,我无法嵌入图像,直到我在stackoverflow上进一步发展!)

答案 2 :(得分:0)

您需要了解如何管理contactAdd数组。您正在创建contactAdd数组,目的是填充100个对象,但您只有四个联系人。

self.contactAdd = [[NSMutableArray alloc]initWithCapacity:100];

这应仅使用实际存在的联系人数量填充。但是你也在向数组添加对象而不管那些最初的100个插槽。

[self.contactAdd addObject:(__bridge id)(person)];

现在,当你选择一个人时,可能没有一个对象可以实际使用,正如你在自己的评论中所指出的那样。

person=(__bridge ABRecordRef)([self.contactAdd objectAtIndex:indexPath.row]);//error here

鉴于你的代码应该发生什么只是简单地创建数组然后让人口自然发生:

self.contactAdd = [[NSMutableArray alloc]init];

此外,在人口中,有一些事情没有多大意义。首先添加人物对象,然后移动人物对象?

[self.contactAdd addObject:(__bridge id)(person)];
[self.contactAdd replaceObjectAtIndex:i withObject:(__bridge id)(person)];

我猜这与原来的100个插槽有关,但删除这个幻数也将删除此步骤。

此外,您正在发布一个您未保留的对象:

ABRecordRef person = (__bridge ABRecordRef)([allPeople objectAtIndex:i]);
//. . . 
CFRelease(person);

我认为您需要查看有关使用表格视图的文档,以便更好地了解这里要完成的工作。但是,要考虑的一件事就是这样做......

self.contactAdd = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);

...因为您正在使用给定的对象。

前两个答案也是正确的,您的cellIdentifier需要在创建时填充字符串。

答案 3 :(得分:0)

我能够使用CFArray解决这个问题,这是其他人需要的代码。 (iphone模拟器5.0)

-(void)reloadAddressBook
{

    if(addressBook)
        CFBridgingRelease(addressBook);
    addressBook = ABAddressBookCreate();
    person=ABAddressBookCopyDefaultSource(addressBook);
    contactAdd=ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(self.addressBook,self.person,0);
    }

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

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];


        if (cell == nil)
            {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
           }

        if(isFiltered)
        {
           self.person = CFArrayGetValueAtIndex(self.filteredData,indexPath.row);
            NSString *tweet=[[NSString stringWithFormat:@"%@",(__bridge_transfer NSString *)ABRecordCopyCompositeName(self.person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

            [cell.textLabel setText:tweet];


        }
        else
        {
            self.person = CFArrayGetValueAtIndex(self.contactAdd, indexPath.row);
            NSString *tweet=[[NSString stringWithFormat:@"%@",(__bridge_transfer NSString *)ABRecordCopyCompositeName(self.person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
             [cell.textLabel setText:tweet];           
        }


        return cell;
    }

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if(isFiltered)
       return CFArrayGetCount(self.filteredData);
    else
    {
        if(CFArrayGetCount(self.contactAdd)==0)
        {
            UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Message"
                                                              message:@"Empty Contacts"
                                                             delegate:nil
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles:nil];
            [message show];
        }

        return CFArrayGetCount(self.contactAdd);
    }
    }