我今天遇到了这个问题。我的应用程序也会在一些特殊的 iDevices 中崩溃。
代码:
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
for (int i = 0; i < nPeople; i++) {
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
// more thing with `person`
}
但它有时会崩溃。添加一些断点发现allPeople的计数小于nPeople。
通过谷歌搜索,我找到了this article。我发现ABAddressBookCopyDefaultSource 可能有问题。这里我得到了默认来源,我必须得到所有来源。
代码:
CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook);
CFIndex sourceCount = CFArrayGetCount(sources);
for (CFIndex i = 0; i < sourceCount; i++) {
ABRecordRef currentSource = CFArrayGetValueAtIndex(source, i);
int sourceType = [(__bridge NSNumber *)ABRecordCopyValue(currentSource, kABSourceTypeProperty) intValue];
switch (sourceType) {
case kABSourceTypeCardDAV:
NSLog(@"kABSourceTypeCardDAV");
break;
case kABSourceTypeCardDAVSearch:
NSLog(@"kABSourceTypeCardDAVSearch");
break;
case kABSourceTypeExchange:
NSLog(@"kABSourceTypeExchange");
break;
case kABSourceTypeExchangeGAL:
NSLog(@"kABSourceTypeExchangeGAL");
break;
case kABSourceTypeLDAP:
NSLog(@"kABSourceTypeLDAP");
break;
case kABSourceTypeLocal:
NSLog(@"kABSourceTypeLocal");
break;
case kABSourceTypeMobileMe:
NSLog(@"kABSourceTypeMobileMe");
break;
default:
break;
}
CFArrayRef allPeopleInSource = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, currentSource, kABPersonSortByLastName);
NSLog(@"Count of allPeopleInSource: %i", CFArrayGetCount(allPeopleInSource));
}
然后我得到了
kABSourceTypeCardDAV
Count of allPeopleInSource: 7
这意味着只有一个来源,并且该来源中只有 7 条记录。
但在我的通讯录中,我有 79 个联系人!
然后我犯了一个错误。我把sources传递给ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering,就像这样:
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, sources, kABPersonSortByLastName);
allPeople 有多少成员?
72!!!
不属于sources的记录数。
我将 CFArrayRef 作为第二个参数传递给 ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering,它需要一个 ABRecordRef。如果我通过nil怎么办?
最后,我得到了代码:
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByLastName);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
for (int i = 0; i < nPeople; i++) {
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
// more thing with `person`
}
现在我可以获取通讯录中的所有联系人。
它在我所有的 iDevices 上都能正常工作!
我很抱歉我的英语不好......
希望这个答案可以帮助你。
注意:现在我不明白地址簿中的source到底是什么,有人可以帮帮我吗?