我正在阅读地址簿联系人...一切顺利,直到我测试联系人没有 名字(因为我可以只用电子邮件或电话或监视器创建联系人....)。 代码(简化)是这样的:
- (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个姓氏联系人姓名 并且只使用姓氏创建一个用于测试目的。
似乎我可以正确地读取任何属性,例如电子邮件或带阵列的地址......但是当联系人缺少名字属性时,应用程序崩溃。
答案 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。