ABRecordCopyValue() EXC_BAD_ACCESS Error

心已入冬 提交于 2019-12-06 02:07:32

While it doesn't seem likely on such a small sampling of an address book, you do have a memory leak here that could be blowing things out.

Assuming you are using arrayOfContacts to determine [self contactsCount], you will be leaking 2 AddressBook items every time through every loop in those class methods.

In this small sample, you will have only leaked 48 AddressBooks by the time you start contactsWithJobTitleProperty. But if you've pulled this from a larger example where you're repeatedly attempting to determine these values on a much larger AddressBook, you could have hundreds of dangling AddressBook objects hanging around.

Add CFRelease as in the following snippet, and see if it helps.

+(NSArray *)arrayOfContacts{

    //Creates an ABAddressBookRef instance containing the data from the address book database
    ABAddressBookRef addressBook = ABAddressBookCreate();

    //Creates an NSArray from the CFArrayRef using toll-free bridging
    NSArray *arrayOfPeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFRelease(addressBook);

    return arrayOfPeople;
}

(fwiw, a separate thing that will crash your program is that you are using NSUInteger as your loop counter type, but you test against a value that could potentially be -1 ... and since 0 is the floor for NSUInteger, if your address book has no contacts in it, this will fail. but that is not why this crash is occurring.)

It looks to me like you may be accessing a NULL value, have you tried testing if it's NULL before performing the bridge transfer?

This might not solve your problem, but I would a couple of adjustments if I were you:

+(NSUInteger)contactsWithJobTitleProperty{
    NSUInteger contactNumber = 0;
    // don't call arrayOfContacts in the loop -- 
    // when you do this you are creating a new address book 
    // each time the loop executes
    NSArray *contacts = [self arrayOfContacts];
    for(NSUInteger increment = 0; increment <= (contacts.count-1); increment++){
        ABRecordRef currentPerson = (__bridge ABRecordRef)[contacts objectAtIndex:increment];
        NSString *valueTest = (__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonJobTitleProperty);

        if(valueTest != NULL) {
            contactNumber++;
        }
    }
    return contactNumber;
}

Also, @john.k.doe mentioned, make sure to use CFRelease(addressBook); in your arrayOfContacts method.

Chase Holland

Just encountered the same issue. See Jokinryou Tsui's answer here.

Basically, if there is a situation where you have different sources of contacts available, and they are not all local (the default), you could end up with a mismatch of counts of how many contacts you're pulling, and try to access an ABRecordRef at an index that doesn't exist. The ABRecordRef will have a value (so a NULL check alone won't do it), but that value will be garbage and you'll get the BAD ACCESS when trying to copy any of its values.

Hope this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!