3

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

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

有没有其他人看到过这样的问题或有任何建议的解决方法?

我正在运行 OS V3.0 的 3G iPhone 上进行测试。该项目是为目标“设备 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 秒的延迟(每次不是同一行代码)。

任何想法,将不胜感激!

当我运行泄漏检查器时,我非常有信心不存在内存管理错误。似乎也没有任何方法可以根据电话号码单独查找联系人。

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

4

3 回答 3

6

如果您无法优化程序,您也可以分叉一个新线程进行加载,然后应用程序可以继续加载并响应用户。

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

-(void)loadContactsInAnotherThread:(void *)obj
{
     NSLog("Do time intensive stuff here.");
}
于 2009-08-21T22:28:50.607 回答
1

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

于 2009-08-21T22:38:10.353 回答
0

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

于 2012-11-21T13:49:49.280 回答