在iPhone ABAddressBook中读取性能问题

时间:2009-08-21 22:08:35

标签: iphone objective-c iphone-sdk-3.0 addressbook

我正在创建一个查找表,将联系电话号码映射到相应的ABRecordRef(我需要这样,这样我就可以根据用户拨打的电话号码有效查找联系人姓名和照片)。

不幸的是,对于500个联系人,需要大约4秒钟来遍历所有联系人并创建我的查找表,这使得我的应用程序加载速度太慢。

是否有其他人遇到过此类问题或有任何建议的解决方法?

我正在测试运行OS V3.0的3G iPhone。该项目是为目标'Device 2.1'而构建的。

以下是代码:

ABAddressBookRef lAddressBook = ABAddressBookCreate();

CFArrayRef lRawAddressBookEntries =
                           ABAddressBookCopyArrayOfAllPeople(lAddressBook);

static NSMutableDictionary sCustomAddressBookPersonRefs =
                       [[NSMutableDictionary alloc] initWithCapacity:1000];

CFIndex lTotalContactsCount = ABAddressBookGetPersonCount(lAddressBook);

/*************************************************************************/
/* Loop through all the contacts storing a pointer to the address book   */
/* entry for each phone number.                                          */
/*************************************************************************/
for (CFIndex i = 0; i < lTotalContactsCount; i++)
{
  ABRecordRef lRef = CFArrayGetValueAtIndex(lRawAddressBookEntries, i);

  ABMultiValueRef lPhoneNumbers = ABRecordCopyValue(lRef,
                                                    kABPersonPhoneProperty);

  CFIndex lContactPhoneNumberCount = ABMultiValueGetCount(lPhoneNumbers);

  /***********************************************************************/
  /* Loop through all the phone numbers available for this contact.      */
  /***********************************************************************/
  for (int j = 0; j < lContactPhoneNumberCount; j++)
  {
    /*********************************************************************/
    /* Get the next phone number and remove the formatting.              */
    /*********************************************************************/
    CFStringRef lPhoneNumber =
      ABMultiValueCopyValueAtIndex(lPhoneNumbers, j);

    [sCustomAddressBookPersonRefs setValue:(id)lRef
                                    forKey:(NSString *)lPhoneNumber];

    CFRelease(lPhoneNumber);
  }      

  CFRelease(lRef);
  CFRelease(lPhoneNumbers);
}

CFRelease(lRawAddressBookEntries);

for循环之前代码的第一部分只需0.2到0.75秒即可运行(包括ABAddressBookCopyArrayOfAllPeople)。

最初在外部for循环中只有一条NSLog行,但我在对设备进行测试之前对其进行了预处理。

在看到问题之后,我在每行代码之间放置了NSLog行,并且没有任何行似乎导致比其他行更长的延迟。使用所有这些跟踪线需要大约50秒来创建查找表,每条线大约需要0.01秒输出,偶尔会有0.1到0.2秒的延迟(每次都不是相同的代码行)。

任何想法都将不胜感激!

我非常有信心因为我运行Leaks检查程序而没有出现内存管理错误。似乎也没有任何方法可以根据电话号码单独查找联系人。

(2009年11月2日)我现在就此问题向Apple提出了错误:
-Bug ID#7357996(性能) - ABAddressBook SDK API性能很差
-Bug ID#7357980(增强功能) - ABAddressBook无法根据电话号码查找联系人

3 个答案:

答案 0 :(得分:6)

如果你无法优化routinue,你也可以为加载分叉一个新线程,然后app可以继续加载并对用户做出响应。

[NSThread detachNewThreadSelector:@selector(_loadContactsInAnotherThread:) toTarget:self withObject:self];

-(void)loadContactsInAnotherThread:(void *)obj
{
     NSLog("Do time intensive stuff here.");
}

答案 1 :(得分:1)

对此真的没有答案。我在AppStore上有一个拨号类型的应用程序,我的应用程序遇到了同样的问题。 AB API在联系人查询方面确实存在限制。你能做的最好的事情是编写一些动画来减少等待时间。

答案 2 :(得分:0)

我在大型地址簿上遇到类似的性能问题。我使用NSPredicates进行匹配,并使用Grand Central Dispatch只从地址簿加载联系人一次,而不是每次请求方法。代码在这里:http://hesh.am/2012/10/lookup-a-contact-name-using-phone-number-in-abaddressbook/