3

アドレス帳を操作しようとしていますが、メモリ管理についての私の理解はせいぜいまあまあです。

私のプロジェクトは自動参照カウント (ARC) を使用していますが、私が学んだように、ARC は Objective-C ランドでのみ保持/解放を管理します。

私の最初の関数呼び出しは、名前ABAddressBookCreate()に含まれるメソッドから取得しているため、「所有する」ABAddressBookRef を返すことを理解していCreateます。私はCFReleaseそれが終わったらそれをします。

私が理解していないのは、このメソッドの過程で ABRecordRef がどのように生き続けるかです。私はしなければならないCFRetainのではないCFReleaseですか?を保持/解放しなかった場合にクラッシュしていた同じクラスに、ほぼ同一の別のメソッドがありABAddressBookRefます。

    ABAddressBookRef iPhoneAddressBook = ABAddressBookCreate();    
    ABRecordRef record = ABAddressBookGetPersonWithRecordID(iPhoneAddressBook, self.addressBookRecordID);

    NSString *firstName = (__bridge_transfer NSString*)ABRecordCopyValue(record, kABPersonFirstNameProperty);
    NSString *lastName = (__bridge_transfer NSString*)ABRecordCopyValue(record, kABPersonLastNameProperty);
    NSString *fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];

    ABMultiValueRef phoneRef = ABRecordCopyValue(record, kABPersonPhoneProperty);

    // Set up an NSArray and copy the values in.
    NSArray *phoneNumberArray = (__bridge_transfer id)ABMultiValueCopyArrayOfAllValues(phoneRef);


    CFRelease(iPhoneAddressBook);

    // Finally, do stuff with contact information in Obj-C land..

終了の質問:最後の行CFReleaseで myを呼び出さないことでリークが発生しましたか?ABMultiValueRef phoneRef

4

1 に答える 1

5

When dealing with Core Foundation memory management, you want to refer to these ownership policies.

The key to your question lies in the "Get Rule", which states that any CF* object you get from and Core Foundation function that contains the word "Get", you don't own it and can't guarantee it's lifespan. The important distinction is between "can't guarantee validity" and "isn't valid". It's possible for you to have a reference to an object that you don't own, but whose lifespan is being supported by some other source. In that case, you'll still be able to use it without crashing.

That's technically what's happening with your ABRecordRef. You haven't taken ownership of it, but it's extremely likely that the ABAddressBookRef that you're getting the record from does own it, and is therefore keeping it alive. As long as that ABAddressBookRef is valid, its records will also be valid. If you were to call CFRelease(iPhoneAddressBook); and then attempt to use the record, I'm betting it would explode.

Finally, for your exit question - Yes, you're leaking the ABMultiValueRef per the "Create" rule, which states that you own objects received via functions containing "Create" or "Copy".

于 2012-06-29T22:06:33.177 に答える