iOS - 内存泄漏地址簿

Yam*_*man 5 memory memory-leaks addressbook ios

当我在应用程序中发现不同类型的内存泄漏时,我正在使用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
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

有人知道哪些线路导致这些泄漏吗?

Rob*_*Rob 5

通常,任何具有CopyCreate名称的Core Foundation方法都应该将所有权转移到ARC对象,或者您必须CFRelease自己调用.因此,您应该转移三个NSString对象的所有权,并手动释放multiRef.

要将所有权转让给ARC,您应该使用CFBridgingRelease,根据WWDC 2012 - 现代Objective-C(视频中约37:35),现在比以前的技术更受欢迎,__bridging_transfer(尽管在幕后它们是相同的)事情).

无论如何,你的三个NSString对象的声明应该是:

NSString *number = CFBridgingRelease(ABMultiValueCopyValueAtIndex(multiRef, 0));
NSString *firstname = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastname = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
Run Code Online (Sandbox Code Playgroud)

这相当于:

NSString *number = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(multiRef, 0);
NSString *firstname = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastname = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
Run Code Online (Sandbox Code Playgroud)

另外,不要忘记发布multiRef:

CFRelease(multiRef);
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果你运行静态分析仪,我相信它会为你指出这些.从"产品"菜单中选择"分析",或按shift+ command+ B.