2

我正在尝试在 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]

当前语言:自动;目前objective-c 2013-08-01 13:11:26.614 Contacts[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”)201 -01 13:11:27.567 联系人[7722:207] 2013-08-01 13:11:27.568 联系人[7722:207] 2 个索引 [0, 2] (gdb)

4

4 回答 4

0

首先为您设置一个值cellIdentifier

static NSString *cellIdentifier = @"CellIdentifier";

于 2013-08-01T07:59:26.343 回答
0

不要没有static NSString *cellIdentifier;价值就离开,例如:

static NSString *cellIdentifier = @"SimpleTableCell"

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

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

(抱歉,在我进一步处理 stackoverflow 之前,我无法嵌入图像!)

于 2013-08-01T08:13:58.003 回答
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需要在创建时填充一个字符串。

于 2013-08-01T10:13:22.407 回答
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);
    }
    }
于 2013-08-08T12:57:32.890 回答