简体   繁体   中英

iOS - Memory leak AddressBook

I was working around AddressBook framework when I've found out some memory leak of different types in my application :

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

Here's my code :

- (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;
}

Do someone know which lines are responsible for these leaks ?

In general, any Core Foundation method that has Copy or Create in the name should either transfer ownership to your ARC objects or you must call CFRelease yourself. Thus, you should transfer ownership for your three NSString objects, and manually release multiRef .

To transfer ownership to ARC you should use CFBridgingRelease , which according to WWDC 2012 - Modern Objective-C (about 37:35 into the video), is now preferred over the previous technique, __bridging_transfer (even though, behind the scenes, they're the same thing).

Anyway, the declarations of your three NSString objects should be:

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

This is equivalent to:

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

Also, don't forget to release multiRef , too:

CFRelease(multiRef);

By the way, if you ran the static analyzer, I believe it would have pointed these out for you. Choose "Analyze" from the "Product" menu, or press shift + command + B .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM