我在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));
}
...
我有什么不对劲,或者我怎么能摆脱警告?
答案 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;
}