在 ARC 下,我有一个 TableView Controller ,它从地址簿中读取每个显示的 TableView 单元格的数据。由于性能原因,我无法在每次调用 tableView:cellForRowAtIndexPath:
时打开地址簿,因此我在 viewDidLoad
中打开它一次,并将对它的引用存储在 >@property (nonatomic) ABAddressBookRef addressBookRef;
会在tableview controller的dealloc
方法中用CFRelease(self.addressBookRef);
释放。
这在我看来是正确的,但是静态分析器在下面的 if
语句的行中提示 viewDidLoad
中的“对象的潜在泄漏”:
- (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));
}
...
我做错了什么,或者我怎样才能摆脱警告?
最佳答案
我相信我找到了解决方案,尽管我不是 100% 确定:
我将存储地址簿引用的属性声明为
@property (strong, nonatomic) id addressBookRef;
并通过
分配给它的引用self.addressBookRef = CFBridgingRelease(ABAddressBookCreateWithOptions (NULL, &error));
这应该将所有权从 CF 转移到 ARC。
在我的代码中,无论我在哪里访问地址簿引用,我都会使用
(__bridge ABAddressBookRef)(self.addressBookRef)
由于保留/释放现在由 ARC 处理,因此不再需要 dealloc 方法中的 CFRelease(self.addressBookRef)
。
编译器警告消失了!
关于iOS:如何在没有 "Potential leak"警告的情况下将 ABAddressBookRef 存储在属性中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21391129/