Проблемы с производительностью чтения в iPhone ABAddressBook - PullRequest
3 голосов
/ 22 августа 2009

Я создаю таблицу соответствия, сопоставляющую номера телефонов контактов с соответствующими им ABRecordRef (мне это нужно, чтобы я мог эффективно искать имена контактов и фотографии на основе номера телефона, набранного пользователем).

К сожалению, для 500 контактов требуется около 4 секунд, чтобы перебрать все контакты и создать мою справочную таблицу, что заставляет мое приложение загружаться слишком медленно.

Кто-нибудь еще видел подобные проблемы или предлагал какие-либо обходные пути?

Я тестирую на iPhone 3G под управлением ОС V3.0. Проект построен для цели «Устройство 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 секунды (не одна и та же строка кода каждый раз).

Любые идеи будут оценены!

Я почти уверен, что ошибок управления памятью нет, так как я запустил проверку утечек. Также, похоже, нет способа найти контакт по отдельности по номеру телефона.

(2 ноября 2009 г.) Я поднял ошибки в Apple по этой проблеме:
Идентификатор ошибки # 7357996 (Производительность) - API-интерфейсы ABAddressBook SDK имеют ужасную производительность
-Bug ID # 7357980 (Улучшение) - ABAddressBook не позволяет искать контакты по номеру телефона

Ответы [ 3 ]

6 голосов
/ 22 августа 2009

Если вы не можете оптимизировать процедуру, вы также можете создать новый поток для загрузки, тогда приложение может продолжать загружаться и отвечать на запросы пользователя.

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

-(void)loadContactsInAnotherThread:(void *)obj
{
     NSLog("Do time intensive stuff here.");
}
1 голос
/ 22 августа 2009

Там действительно нет ответа на это. У меня есть приложение для набора номера в AppStore, и мое приложение страдает от той же проблемы. AB API действительно ограничивает с точки зрения запроса контактов. Лучшее, что вы можете сделать - это написать анимацию, чтобы сделать ожидание менее болезненным.

0 голосов
/ 21 ноября 2012

У меня были похожие проблемы с производительностью больших адресных книг. Я использовал NSPredicates для сопоставления и Grand Central Dispatch для загрузки контактов из адресной книги только один раз, а не каждый раз, когда запрашивается метод. Код здесь: http://hesh.am/2012/10/lookup-a-contact-name-using-phone-number-in-abaddressbook/

...