1

アドレスブックから連絡先をコピーするコードがいくつかあります。連絡先の数が少ない場合は完全に機能します。現在、私の電話には1200の連絡先があり、それらをコピーしようとするとアプリがクラッシュします。このコードの最適化やコードの書き直しを手伝ってくれる人はいますか? 私が使用しているコードを以下に追加します。

ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    NSString *requestContactsString = @"<contacts>";    


    for (int i=0; i<nPeople; i++)
    {
        NSLog(@"Started : %d", i);

        ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
        CFTypeRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
        CFTypeRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
        CFTypeRef email = ABRecordCopyValue(ref, kABPersonEmailProperty);
        CFTypeRef phone = ABRecordCopyValue(ref, kABPersonPhoneProperty);

        requestContactsString = [requestContactsString stringByAppendingFormat:@"<item>"];

        if(firstName)
        {
            requestContactsString = [requestContactsString stringByAppendingFormat:@"<firstname>%@</firstname>", firstName];
            CFRelease(firstName);
            firstName = nil;
        }
        if(lastName)
        {
            requestContactsString = [requestContactsString stringByAppendingFormat:@"<lastname>%@</lastname>", lastName];
            CFRelease(lastName);
            lastName = nil;
        }
        if(email)
        {
            if(ABMultiValueGetCount(email)>0)
            {
                CFTypeRef em = ABMultiValueCopyValueAtIndex(email, 0);
                requestContactsString = [requestContactsString stringByAppendingFormat:@"<email>%@</email>", em];
                CFRelease(em);
            }
            CFRelease(email);
            email = nil;
        }
        if(phone)
        {
            if(ABMultiValueGetCount(phone)>0)
            {
                CFTypeRef ph = ABMultiValueCopyValueAtIndex(phone, 0);
                requestContactsString = [requestContactsString stringByAppendingFormat:@"<phone>%@</phone>", ph];
                CFRelease(ph);
            }
            CFRelease(phone);
            phone = nil;
        }

        requestContactsString = [requestContactsString stringByAppendingFormat:@"</item>"];
    }


    if(allPeople)
    {
        CFRelease(allPeople);
        allPeople = nil;
    }
    if(addressBook)
    {
        CFRelease(addressBook);
        addressBook = nil;
    }

    requestContactsString = [requestContactsString stringByAppendingFormat:@"</contacts>"];

    NSString *hashedContactsString = [self generateHashedPassword:requestContactsString];
4

2 に答える 2

3

私が見ることができる主な非効率性は、呼び出されるたびに[NSString stringByAppendingFormat]新しいオブジェクトを作成するという使用です。これは、次の実行ループまで使用されなくなった長い自動解放オブジェクトがNSString多数あることを意味します(ただし、ARC を使用している場合は状況が改善される可能性があります)。NSString

代わりに( referencerequestContactsString ) を作成しNSMutableStringて使用することで、メモリをより有効に活用し、パフォーマンスを向上させることができると思います。これにより、既存のオブジェクトが変更され、新しい文字列を受け入れるためにより多くのメモリが割り当てられます。[NSMutableString appendString]

各追加は次のようになります。

[requestContactsString appendString:[NSString stringWithFormat:@"<lastname>%@</lastname>", lastName]];

それでも多数の自動解放オブジェクトが作成されますが、それらははるかに小さくなります。

于 2012-07-06T05:55:34.987 に答える
1

を使用し、メソッドNSMutableStringで XML を構築します。appendFormat:ループでは、これまでに組み立てた文字列全体を複数回コピーしています。

于 2012-07-06T05:57:07.547 に答える