2009-08-21 54 views
3

我正在創建一個查找表,將聯繫人電話號碼映射到其相應的ABRecordRef(我需要這個,以便我可以根據用戶撥打的電話號碼有效查找聯繫人姓名和照片)。在iPhone中讀取性能問題ABAddressBook

不幸的是,對於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秒的延遲(每次都不是相同的代碼行)。

任何想法,將不勝感激!

我非常自信沒有內存管理錯誤,因爲我運行了泄漏檢查程序。根據電話號碼,似乎也沒有任何方法單獨查找聯繫人。

(2日2009年11月),我現在已經提出了與蘋果的bug針對此問題:
-Bug ID#7357996(性能) - ABAddressBook SDK的API有可怕的性能
-Bug ID#7357980(增強) - ABAddressBook提供沒有辦法根據電話號碼查找聯繫人

+0

蘋果告訴我,Bug ID#7357996是一個已知Bug ID#5721841的副本,工程部門正在調查。 – 2009-11-05 16:49:20

回答

6

如果您無法優化程序,也可以爲加載分叉新線程,那麼應用程序可以繼續加載並對用戶作出響應。

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

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

謝謝,這似乎很好地工作。我相信我會有一些併發錯誤來解決,但它現在看起來不錯... – 2009-08-24 03:18:54

+0

非常感謝代碼和答案! – Martin 2010-01-18 14:55:51

1

這真的沒有答案。我在AppStore上有一個撥號器類型的應用程序,我的應用程序遭受同樣的問題。 AB API在聯繫人查詢方面非常有限。你可以做的最好的事情是編寫一些動畫來減少等待的痛苦。