ios - ABAddressBook 和 CFRelease 的奇怪之处

标签 ios automatic-ref-counting abaddressbook

ABAddressBook 发生了一件奇怪的事情。这是一些代码:

- (NSArray*)addressBookArray {

    ABAddressBookRef addressBook = NULL;
    NSArray *temp = nil;

    if(&ABAddressBookCreateWithOptions != NULL) {

        CFErrorRef error = nil;
        addressBook = ABAddressBookCreateWithOptions(NULL, &error);
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {

            dispatch_async(dispatch_get_main_queue(), ^{
                if(error) {
                    // handle error
                }
                else if(!granted) {
                    // handle not granted
                }
            });
        });
    }
    else { // iOS 5
        addressBook = ABAddressBookCreate();
    }
    if(addressBook) {
        temp = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
        CFRelease(addressBook);
    }
    return temp;
}

- (NSArray*)emailList {

    NSArray *temp = [self addressBookArray];
    NSMutableArray *list = nil;

    if(temp) {

        int n = temp.count;
        list = [NSMutableArray arrayWithCapacity:n];

        for(int i = 0; i < n ; i++) {

            ABRecordRef person = (__bridge ABRecordRef)[temp objectAtIndex:i];
            NSString *name = (__bridge_transfer NSString*)ABRecordCopyCompositeName(person);

            if(name) {
                ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);

                if(emails) {
                    int cnt = ABMultiValueGetCount(emails);

                    for(int j = 0; j < cnt; j++) {
                        NSString *email = (__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(emails, j);

                        if(email) {
                            [list addObject:email];
                            break;
                        }
                    }
                    CFRelease(emails);
                }
            }
        }
    }
    return list;
}

如果我调用 emailList 并注释掉 CFRelease(addressBook),我会在 XCode 的分析中收到可能泄漏的警告,但我的代码运行正常。

如果我取消注释 CFRelease(addressBook),则没有泄漏警告,ABRecordRef personNSString *name 具有正确的值,但是 ABMultiValueRef 电子邮件 如果始终为零。

困惑。

最佳答案

虽然这让我有些吃惊,但我怀疑 ABPerson 没有它的 ABAddressBook 就没有完全定义。因此地址簿需要与人存在的时间一样长。鉴于此,只要这都是单线程的,您可能希望将 ABAddressBook 存储在一个 ivar 中,这样您就不必一直创建和销毁它。如果它是多线程的,请记住每个线程需要一个单独的 ABAddressBook

关于ios - ABAddressBook 和 CFRelease 的奇怪之处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14242649/

相关文章:

ios - 如何在UITableView的UiLabel中单击特定位置?

objective-c - 使用 ARC,如何正确设置具有副作用的属性?

ios - SFSafariViewController 完成按钮不起作用

ios - 自定义初始化程序 "initWithImage"未在 View 中显示图像

ios - swift:ARC:如何释放对 UIImage 的所有引用

iphone - 钥匙串(keychain) ARC 错误

swift - 请求访问地址簿时应用程序卡住

ios - 从地址簿中获取电话号码

ios - 无法访问 kABPersonNoteProperty

ios - Firebase 的 iOS 离线功能与核心数据