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

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

要将所有权转移给 ARC,您应该使用CFBridgingRelease,根据WWDC 2012 - Modern 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));

这相当于:

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

另外,也不要忘记发布multiRef

CFRelease(multiRef);

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

于 2013-01-02T13:26:03.243 回答