iOS:如何在没有“潜在泄漏”警告的属性中存储ABAddressBookRef?

时间:2014-01-27 20:35:09

标签: ios memory-leaks addressbook

我在ARC下有一个tableview控制器,它从每个显示的tableview单元格的地址簿中读取数据。由于性能原因,我无法为tableView:cellForRowAtIndexPath:的每次通话打开地址簿,我在viewDidLoad打开一次,并将其引用存储在@property (nonatomic) ABAddressBookRef addressBookRef;它将随CFRelease(self.addressBookRef);一起发布{1}}在tableview控制器的dealloc方法中 这在我看来是正确的,但静态分析器在下面viewDidLoad语句的行if中抱怨“对象的潜在泄漏”:

- (void)viewDidLoad{
    [super viewDidLoad];
    CFErrorRef error = nil;
    self.addressBookRef = ABAddressBookCreateWithOptions (NULL, &error);
    if (self.addressBookRef == nil) {
        NSLog(@"%@: %@: Could not open addressbook", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
    }

...

我有什么不对劲,或者我怎么能摆脱警告?

2 个答案:

答案 0 :(得分:1)

我相信我找到了解决办法,虽然我不是百分百肯定:
我声明了将地址簿引用存储为

的属性
@property (strong, nonatomic) id addressBookRef;

并通过

分配对它的引用
self.addressBookRef = CFBridgingRelease(ABAddressBookCreateWithOptions (NULL, &error));  

这应该将所有权从CF转移到ARC 在我的代码中,无论我在何处访问地址簿参考,我都是使用

进行的
(__bridge ABAddressBookRef)(self.addressBookRef)  

由于保留/释放现在由ARC处理,因此不再需要dealloc方法中的CFRelease(self.addressBookRef)
并且编译器警告消失了!

答案 1 :(得分:0)

您可以覆盖setAddressBookRef:以保留地址簿参考,并在分配属性后将其释放。

像这样的东西。您将要检查NULL,因为使用它调用CFRetain / Release将导致运行时错误。

- (void)setAddressBookRef:(ABAddressBookRef)addressBook
{
    CFRetain(addressBook);
    CFRelease(_addressBookRef);
    _addressBookRef = addressBook;
}