当需要返回对象时,释放对象的正确方法是什么

时间:2014-03-24 03:50:58

标签: ios memory-leaks

我做了Analyze并在下面的代码中发出potential leak of an object stored into警告

+ (ABAddressBookRef)getABAddressBookRef {
    unsigned long long lastAddressBookGeneration = _addressBookGeneration;
    unsigned long long addressBookGeneration =[[NSThread currentThread].threadDictionary[kAddressBookGeneration] unsignedLongLongValue];
    ABAddressBookRef addressBook = (__bridge ABAddressBookRef)[NSThread currentThread].threadDictionary[kAddressBook];

    if (addressBook == nil || (addressBookGeneration != lastAddressBookGeneration)) {
        if (addressBook) {
            if ([NSThread isMainThread]) {
                ABAddressBookUnregisterExternalChangeCallback(addressBook,_ExternalChangeCallback, nil);
            }
            [[NSThread currentThread].threadDictionary removeObjectForKey:kAddressBook];
        }
        addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
        if (addressBook != nil) {
            if ([NSThread isMainThread]) {
                ABAddressBookRegisterExternalChangeCallback(addressBook,_ExternalChangeCallback, nil);
            }

            [NSThread currentThread].threadDictionary[kAddressBook] = (__bridge id) addressBook;
            [NSThread currentThread].threadDictionary[kAddressBookGeneration] = [NSNumber numberWithUnsignedLongLong:lastAddressBookGeneration];
        }

    }
    return addressBook;
}

我环顾四周,发现问题可能是ABAddressBookCreateWithOptions(NULL, NULL);我可能需要在调用之后调用CFRelease()。但接着,我的下一个问题出现了:在这个方法中,我需要返回addressBook。我怎样才能实现这两点1)返回ABAddressBookRef 2)正确调用CFRelease()所以我没有得到内存泄漏警告?

这有意义吗?

+ (ABAddressBookRef)getABAddressBookRef {
    unsigned long long lastAddressBookGeneration = _addressBookGeneration;
    unsigned long long addressBookGeneration =[[NSThread currentThread].threadDictionary[kAddressBookGeneration] unsignedLongLongValue];
    ABAddressBookRef addressBook = (__bridge ABAddressBookRef)[NSThread currentThread].threadDictionary[kAddressBook];

    if (addressBook == nil || (addressBookGeneration != lastAddressBookGeneration)) {
        if (addressBook) {
            if ([NSThread isMainThread]) {
                ABAddressBookUnregisterExternalChangeCallback(addressBook,_ExternalChangeCallback, nil);
            }
            [[NSThread currentThread].threadDictionary removeObjectForKey:kAddressBook];
        }
        ABAddressBookRef newAddressBook = ABAddressBookCreateWithOptions(NULL, NULL);
        addressBook = newAddressBook;
        if (newAddressBook != nil) {
            if ([NSThread isMainThread]) {
                ABAddressBookRegisterExternalChangeCallback(newAddressBook, _ExternalChangeCallback, nil);
            }

            [NSThread currentThread].threadDictionary[kAddressBook] = (__bridge id) newAddressBook;
            [NSThread currentThread].threadDictionary[kAddressBookGeneration] = [NSNumber numberWithUnsignedLongLong:lastAddressBookGeneration];
            CFRelease(newAddressBook);
        }
    }
    return addressBook;
}

1 个答案:

答案 0 :(得分:2)

您可以轻松模拟自动释放

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
    CFRelease(newAddressBook);
});