代码之家  ›  专栏  ›  技术社区  ›  Dan J Akhil

在iPhone AbAddressBook中读取性能问题

  •  3
  • Dan J Akhil  · 技术社区  · 15 年前

    我正在创建一个查找表,将联系人电话号码映射到相应的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秒就可以运行(包括abAddressBookCopyArrayFallPeople)。

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

    看到这个问题后,我将nslog行放在每行代码之间,并且没有一行似乎比其他行造成明显更长的延迟。对于所有这些跟踪行,创建查找表需要大约50秒,每行输出大约需要0.01秒,偶尔会有0.1到0.2秒的延迟(每次代码行不同)。

    任何想法都会受到赞赏!

    我很有信心在运行泄漏检查程序时没有内存管理错误。也没有任何方法可以根据联系人的电话号码单独查找联系人。

    (2009年11月2日)我现在已经和苹果一起提出了这个问题:
    -Bug ID 7357996(性能)-AbAddressBook SDK API的性能很差
    -Bug ID 7357980(增强)-AbAddressBook无法根据电话号码查找联系人

    3 回复  |  直到 12 年前
        1
  •  6
  •   NWCoder    15 年前

    如果你不能优化路由,你也可以分叉一个新的线程进行加载,然后应用程序可以继续加载并对用户作出响应。

    [NSThread detachNewThreadSelector:@selector(_loadContactsInAnotherThread:) toTarget:self withObject:self];
    
    -(void)loadContactsInAnotherThread:(void *)obj
    {
         NSLog("Do time intensive stuff here.");
    }
    
        2
  •  1
  •   erotsppa    15 年前

    这真的没有答案。我在AppStore上有一个拨号程序类型的应用程序,我的应用程序也遇到了同样的问题。ab api在联系人查询方面是非常有限的。你能做的最好的事情就是在一些动画中进行编码,以减少等待的痛苦。

        3
  •  0
  •   Hesham    12 年前

    我在大型通讯簿上的表现也有类似的问题。我使用nspredicates进行匹配,并使用Grand Central Dispatch只从通讯簿加载一次联系人,而不是每次请求该方法。代码如下: http://hesh.am/2012/10/lookup-a-contact-name-using-phone-number-in-abaddressbook/