5

アプリケーションでさまざまなタイプのメモリ リークを発見したとき、私は AddressBook フレームワークに取り組んでいました。

Leaked Object   #   Address Size    Responsible Library Responsible Frame
__NSCFArray 8   < multiple >    256 Bytes   AddressBook ABCMultiValueInsertAndCreateIdentifier
__NSCFString    7   < multiple >    224 Bytes   AppSupport  _sqliteStatementApplyValuesFromRecordWithNullValue
Malloc 32 Bytes 8   < multiple >    256 Bytes   AddressBook ABCMultiValueInsertAndCreateIdentifier
__NSCFArray 8   < multiple >    256 Bytes   AddressBook ABCMultiValueInsertAndCreateIdentifier
ABCMultiValue   8   < multiple >    256 Bytes   AddressBook ABCMultiValueCreate
Malloc 32 Bytes 7   < multiple >    224 Bytes   AddressBook ABCMultiValueInsertAndCreateIdentifier
__NSCFArray 7   < multiple >    224 Bytes   AddressBook ABCMultiValueInsertAndCreateIdentifier
Malloc 32 Bytes 5   < multiple >    160 Bytes   AddressBook ABCMultiValueInsertAndCreateIdentifier

これが私のコードです:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    SDAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    ABMultiValueRef multiRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
    NSString *number = (__bridge NSString *) ABMultiValueCopyValueAtIndex(multiRef, 0);
    NSString *firstname = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSString *lastname = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

    number = (number ? number : @"");
    firstname = (firstname ? firstname : @"");
    lastname = (lastname ? lastname : @"");

    NSDictionary *dic = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:number, firstname, lastname, nil] forKeys:[NSArray arrayWithObjects:kSDPhoneNumberKey, kSDFirstnameKey, kSDLastnameKey, nil]];

    NSMutableArray *numberArray = [NSMutableArray arrayWithArray:appDelegate.contactArray];
    [numberArray addObject:dic];

    [appDelegate setContactArray:numberArray];

    [self.tableView reloadData];

    [self dismissModalViewControllerAnimated:YES];

    return NO;
}

これらのリークの原因となっている行を知っている人はいますか?

4

1 に答える 1

5

Copy一般に、名前にまたはが含まれる Core Foundation メソッドはCreate、所有権を ARC オブジェクトに譲渡するか、CFRelease自分自身を呼び出す必要があります。したがって、3 つのNSStringオブジェクトの所有権を譲渡し、手動で を解放する必要がありますmultiRef

WWDC 2012 - Modern Objective-C (ビデオの約 37:35) によると、これは現在、以前の手法よりも優先されていますCFBridgingRelease(ただし、舞台裏では同じです)。もの)。__bridging_transfer

とにかく、3 つのNSStringオブジェクトの宣言は次のようにする必要があります。

NSString *number = CFBridgingRelease(ABMultiValueCopyValueAtIndex(multiRef, 0));
NSString *firstname = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastname = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));

これは次と同等です。

NSString *number = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(multiRef, 0);
NSString *firstname = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastname = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

また、 release も忘れないでくださいmultiRef:

CFRelease(multiRef);

ちなみに、静的アナライザーを実行した場合は、これらが指摘されると思います。「製品」メニューから「分析」を選択するか、shift+ command+を押しますB

于 2013-01-02T13:26:03.243 に答える