2011-09-19 56 views
6

我有一个应用程序偶尔崩溃,由于ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering()具有与ABAddressBookGetPersonCount()不同的大小返回的数组。代码的外壳如下所示。通常nPeople与数组大小相同。但是,在一个用户的iPhone上(或者至少由一个用户报告),nPeople几乎是两倍大。我可以通过使用数组大小​​而不是ABAddressBookGetPersonCount()来停止崩溃。但是,我不确定这是否意味着我没有访问iPhone中的所有联系人。ABAddressBookCopyArrayOfAllPeople和ABAddressBookGetPersonCount返回不同的大小

  • 有没有人遇到过这个问题?
  • 为什么数字会不一样?

我想知道这是否与联系人存储在组中(我不知道有团体 - 只是一个想法)。另外,从用户的电子邮件地址,我怀疑他们使用MobileMe。我想知道,如果与MobileMe同步将创建具有不同recordId的重复项,但不会删除现有联系人,至少不会达到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); 
    } 

回答

13

ABAddressBookGetPersonCountABAddressBookCopyArrayOfAllPeople给出不同的阵列。

ABAddressBookGetPersonCount - 返回地址簿中人员记录的数量。 ABAddressBookCopyArrayOfAllPeople - 返回地址簿中的所有人员记录。

因此有时候同一个人可能会有额外的记录。这就是为什么你可能会得到不同的尺寸。

+0

这意味着ABAddressBookGetPersonCount应该始终小于ABAddressBookCopyArrayOfAllPeople? –

+0

这取决于。如果同一个人可能有额外的记录,这将是不同的。如果每个人都有一个联系号码。那么两者将是相同的。 :) @NikitaP –

9

我今天遇到这个问题。我的应用程序也在一些特殊的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个联系人!

然后我犯了一个错误。我通过sourcesABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering,就像这样:

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在通讯录准确地说,任何人可以帮助我吗?

+0

很好的答案。有时,地址簿中的所有联系人可能不是来自一个来源。它可能来自Facebook,不同的gmail等。所以如果你不指定一个源,你会得到所有的联系人。 – Kaey

相关问题