gui*_*man 6 iphone iphone-sdk-3.0 abaddressbook ios4 ios
我有一个应用程序偶尔会崩溃,因为ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering()返回的数组与ABAddressBookGetPersonCount()的大小不同.代码的shell如下所示.通常nPeople与数组大小相同.然而,在一个用户的iPhone上(或者至少,如一个用户所报告的那样),nPeople几乎是其两倍.我可以通过使用数组大小而不是ABAddressBookGetPersonCount()来停止崩溃.但是,我不确定这是否意味着我没有访问iPhone中的所有联系人.
我想知道这是否与存储在群组中的联系人有关(我不知道有群组 - 只是一个想法).此外,从用户的电子邮件地址,我怀疑他们使用MobileMe.我想知道是否与MobileMe同步会创建具有不同recordId的重复项,但不会删除现有的Contact,至少不会像ABAddressBookGetPersonCount()那样.
编辑:我已经对此进行了一些调查,并对问题的原因有一个相当好的想法.由于我想要一个排序的联系人数组,我使用了ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering().这需要一个地址簿源 - 我使用了默认源.我相信可以有各种来源 - 本地来源以及Exchange和MobileMe等其他来源.因此,我的数组最终将只有本地联系人,而ABAddressBookGetPersonCount()返回的数字将包括所有来源 - 因此我的崩溃.因此,我认为最好只使用我的应用程序中的本地数据,并使用ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering而不是ABAddressBookGetPersonCount返回的数组大小.
CFArrayRef allPeople = InSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
for (int i = 0; i < nPeople; i++)
{
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
}
Run Code Online (Sandbox Code Playgroud)
Som*_*luk 13
ABAddressBookGetPersonCount和ABAddressBookCopyArrayOfAllPeople给出不同的数组.
ABAddressBookGetPersonCount - 返回通讯录中的人员记录数.ABAddressBookCopyArrayOfAllPeople - 返回通讯录中的所有人员记录.
所以有时候同一个人可能会有额外的记录.这就是为什么你可能会有不同的尺寸.
我今天遇到了这个问题.我的应用程序也崩溃了一些特殊的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`
}
Run Code Online (Sandbox Code Playgroud)
但它有时会崩溃.添加一些断点我发现它allPeople的数量小于nPeople.
通过谷歌搜索,我发现了这篇文章.我发现可能有问题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));
}
Run Code Online (Sandbox Code Playgroud)
然后我得到了
kABSourceTypeCardDAV
Count of allPeopleInSource: 7
Run Code Online (Sandbox Code Playgroud)
这意味着该来源中只有一个来源,只有7个记录.
但在我的地址簿中,我有79个联系人!
然后我犯了一个错误.我通过sources对ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering,就像这样:
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, sources, kABPersonSortByLastName);
Run Code Online (Sandbox Code Playgroud)
有多少成员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`
}
Run Code Online (Sandbox Code Playgroud)
现在我可以在通讯录中找到所有联系人.
它适用于我的所有iDevices!
我对我可怜的英语感到非常抱歉......
希望这个答案可以帮到你.
注意:现在我不完全理解sourceAddressBook中的内容,有人可以帮助我吗?