iOS: How to store an ABAddressBookRef in a property without a "Potential leak" warning?

StackOverflow https://stackoverflow.com/questions/21391129

  •  03-10-2022
  •  | 
  •  

문제

I have, under ARC, a tableview controller that reads data from the address book for every shown tableview cell. Since for performance reasons I cannot open the address book for every call to tableView:cellForRowAtIndexPath:, I open it once in viewDidLoad and to store the reference to it in a @property (nonatomic) ABAddressBookRef addressBookRef; It will be released with CFRelease(self.addressBookRef); in the dealloc method of the tableview controller.
This seems to me to be correct, but the static analyzer complains about a "Potential leak of an object" in viewDidLoad in the line of the if statement below:

- (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));
    }

...

Do I something wrong, or how could I get rid of the warning?

도움이 되었습니까?

해결책 2

You could override setAddressBookRef: so that it retains the address book ref, and release it after assign the property.

Something like this. You'll want to check for NULL, since calling CFRetain/Release with it will cause a runtime error.

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

다른 팁

I believe I found the solution, although I am not 100% sure:
I declared the property that stores the address book reference as

@property (strong, nonatomic) id addressBookRef;

and assigned the reference to it by

self.addressBookRef = CFBridgingRelease(ABAddressBookCreateWithOptions (NULL, &error));  

This should transfer the ownership from CF to ARC.
In my code, wherever I access the address book reference, I do it using

(__bridge ABAddressBookRef)(self.addressBookRef)  

And since retain/release is now handled by ARC, the CFRelease(self.addressBookRef) in the dealloc method is no longer necessary.
And the compiler warning is gone!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top