kABPersonFirstNameProperty ... trowing EXC_BAD_ACCESS

时间:2010-02-15 19:07:30

标签: iphone objective-c memory-management exc-bad-access abaddressbook

我正在阅读地址簿联系人...一切顺利,直到我测试联系人没有 名字(因为我可以只用电子邮件或电话或监视器创建联系人....)。 代码(简化)是这样的:

- (NSMutableArray *) getContactsInfo {
    NSMutableArray *contactsList = [[NSMutableArray alloc] init];
    localAddressBook = ABAddressBookCreate();

    int contactsLength = (int)ABAddressBookGetPersonCount(localAddressBook);

    if (contactsLength < 1)
        return nil;

    for(int currentContact=1; currentContact < (contactsLength + 1); currentContact++) {
        ABRecordRef person = ABAddressBookGetPersonWithRecordID(localAddressBook,(ABRecordID) currentContact);

        firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        NSLog(@"%@", firstName);

        [contactsList addObject:firstName];
        CFRelease(person);
    }

    return contactsList;
}

我得到的输出是:

2010-02-15 14:16:25.616 testApp[7065:207] Contact0
2010-02-15 14:16:25.618 testApp[7065:207] Contact1
2010-02-15 14:16:25.619 testApp[7065:207] Contact2
Program received signal:  “EXC_BAD_ACCESS”.

我有3个姓氏联系人姓名 并且只使用姓氏创建一个用于测试目的。

似乎我可以正确地读取任何属性,例如电子邮件或带阵列的地址......但是当联系人缺少名字属性时,应用程序崩溃。

4 个答案:

答案 0 :(得分:4)

你在代码中做了一些非常错误的事情:你假设记录ID是连续的并且从1开始。根本不是这种情况,你不能依赖它。

您应该使用ABAddressBookCopyArrayOfAllPeople来查找通讯簿中的所有记录,然后使用Core Foundation CFArray函数来获取各个项目。

(是的,iPhone中的地址簿API非常糟糕)

答案 1 :(得分:1)

您可能希望enable NSZombies查看EXC_BAD_ACCESS的确切位置。

答案 2 :(得分:0)

要确保崩溃发生在 ABRecordCopyValue,而不是第一次尝试使用firstName时(可能是NULL?)此外, person也不是NULL,对吗? (一般来说,问题中的更多代码以及关于哪一行崩溃的详细信息会有所帮助。)

要尝试的另一件事是将person投射到ABRecord*并使用[valueForProperty][1];这两种类型是免费桥接,你可能会从后者得到不同的结果(虽然我对此表示怀疑)。

更新:根据您发布的代码,您需要在尝试通过firstName输出之前检查NSLog是否为空 - 很可能{{1只是返回NULL(表示该记录没有第一个名称数据。)您还应该检查ABRecordCopyValue ref值本身的有效性 - 将NULL传递给person可能是其他问题的根源。

答案 3 :(得分:0)

问题确实是一个零名 - 但不是在日志语句中,而是在尝试将nil插入数组的地方。您不能将nil值插入数组,这会导致崩溃。 NSLog还没有将输出刷新到控制台,这就是为什么你还没有看到你的上一个日志声明说第一个名字是nil。

任何时候从地址簿中获取数据,在将其插入任何内容之前,请检查该值是否为nil。