2012-01-08 4 views
3

私は興味のある連絡先を探すために、アドレス帳のデータを読む必要があるアプリを書いています。アプリは今日(Viber、Whatsapp、Tango ...のように)行う。私はマッチングを行う必要があるので、データをサーバに送信し、クライアントに返信すると、そのデバイスに同じアプリがインストールされています。他のアプリ(Viber、Whatsapp ...のような)のように速くアドレス帳を読む方法

私は論理またはそのアイデアのメカニズムに問題はありません、私の問題はスピードです!私は欲しいことをすることができましたが、プロセスはiPhone4で終了するまでに27秒かかり、500件の連絡先がありました。同じデバイスで、ViberやWhatsapp(または類似のアプリ)を試してみると、プロセスは5秒以下で完了します。

私の方法は非常に簡単です。私はforループを行い、すべてを読みます。同じことを他のアプリのようにもっと速くするにはどうすればいいですか?

//variable definitions 
    ABAddressBookRef addressBook = ABAddressBookCreate(); 
    CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook); 
    CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(people), people); 

    //sort the contents of the Mutable Array 
    CFArraySortValues(peopleMutable, CFRangeMake(0, CFArrayGetCount(peopleMutable)), (CFComparatorFunction) ABPersonComparePeopleByName, (void*) ABPersonGetSortOrdering()); 

    //read the Address Book 
    NSString *fullName, *number; 
    ABRecordRef record = ABPersonCreate(); 
    ABMutableMultiValueRef multi; 
    int contactID; 
    int nameCount=0;//used to count the names in the string to send to server 
    NSMutableString *strNamesToSend = [[NSMutableString alloc] init]; 

    for(CFIndex i=0; i< CFArrayGetCount(people); i++) 
    { 
     record = CFArrayGetValueAtIndex(people, i); 
     multi = ABRecordCopyValue(record, kABPersonPhoneProperty); 

     //Contact ID 
     contactID = (int)ABRecordGetRecordID(record); 

     //Full Name 
     fullName = [NSString stringWithFormat:@"%@ %@", (NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty), (NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty)]; 
     fullName = [fullName stringByReplacingOccurrencesOfString:@" (null)" withString:@""]; 

     //fill data into AddressBook Table 
     if(dbOpen == SQLITE_OK) 
     { 
      //pure sqlite3 work to save the names in my app 
     } 

     //Get multiple numbers from each user (if any) 
     for(CFIndex j=0; j<ABMultiValueGetCount(multi); j++) 
     { 
      number = (NSString *)ABMultiValueCopyValueAtIndex(multi, j); 

      nameCount++; 

      //fill data into AllNumbers Table 
      if(dbOpen == SQLITE_OK) 
      { 
       //another sqlite3 work to save the numbers 
      } 
     } 

     //send to the server every 29 numbers so we don't send all the 500 numbers at once 
     if(nameCount > 29) 
     { 
      //send to server 
     } 
+0

あなたは、その時間がどこで使われているかを見るためにそれをプロファイリングしましたか?データをサーバーに同期して送信していますか? –

答えて

5

はあなたがすべてであなたのコードをプロファイリングしようとしたことがあり:ここで

私が使用するコードはありますか?プロファイラは、コードの遅い部分をすばやく識別できる必要があります。

非常に簡単な検査から、私はあなたが一回ではなく各繰り返しで配列のサイズを数えていることに気付きました。あなたのループの外に移動します:

int count = CFArrayGetCount(people); 
for (CFIndex i = 0; i < count; i++) 

あなたは、詳細SQLは、あなたが作っているコールしませんが、SQLITE_OKのためにチェックしているという事実は、あなたがループを介してデータベースを毎回開いていることを意味します。このような場合は、毎回データベースを開くのではなく、この呼び出しをループ外に移動する必要があります。

私は、nameCountがリセットされていないことに気付きました。つまり、29に達すると、毎回のケースがヒットするため、膨大なネットワークリクエストが発生します。

+0

私は配列の外にカウントを移動し、SQLITE_OKの問題を削除しようとします。変数nameCountはリセットされていますが、コードのポスティングを最小限に抑えるためにこの部分を省略しました。最後のifステートメントでリセットされます。私はプロファイラが何であるか分かりません。私は瞬時に新しい時間を費やしてあなたを更新し、ありがとう:) – antf

+0

ところで、それは非常に基本的なので、私はデータベースの部分を省略したが、あなたがそれが必要と感じたら私はそれを投稿します。 – antf

+0

あなたが提案した変更を試しましたが、まだ27秒かかりました – antf

関連する問題