Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ABRecordCopyValue() EXC_BAD_ACCESS Error

In my app, I have to retrieve certain properties of the users contacts. For example, I need to retrieve a contact's first name, last name, middle name, nickname, organization, job title, department, birthday, email, etc. I have some methods to retrieve these properties, and only a couple work, even though they all are very similar. Here is my code for one method that is working (first name) and one that is not (job title):

+(NSString *)fetchFirstnameForPersonID: (NSUInteger)identifier{

    NSString *firstName;
    ABRecordRef currentPerson = (__bridge ABRecordRef)[[PSAddressBook arrayOfContacts] objectAtIndex:identifier];

    //If the first name property exists
    if ((__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonFirstNameProperty) != NULL){
    
        firstName = (__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonFirstNameProperty);        
    }    
    //If the first name property does not exist
    else{
        firstName = @"NULL";
    }
    return firstName;    
}

+(NSString *)fetchJobTitleForPersonID: (NSUInteger)identifier{

    NSString *jobTitle;
    ABRecordRef currentPerson = (__bridge ABRecordRef)[[PSAddressBook arrayOfContacts] objectAtIndex:identifier];

    if ((__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonJobTitleProperty) != NULL){
    
        jobTitle = (__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonJobTitleProperty);        
    }    
    else{
    
        jobTitle = @"NULL";
    }
    return jobTitle;    
}

arrayOfContacts is a class method defined like this:

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

These methods are defined in a model class called "PSPropertyFetcher". In my root view controller, I put some NSLog statements in viewDidLoad to see if the property fetcher methods are working properly. Here is my code for the tests:

NSLog(@"Property Fetchers Test\n");

for(NSUInteger i = 0; i <= ([PSAddressBook contactsCount]-1); i++){

    NSLog(@"First Name: %@", [PSPropertyFetcher fetchFirstnameForPersonID:i]);
    NSLog(@"Middle Name: %@", [PSPropertyFetcher fetchMiddlenameForPersonID:i]);
    NSLog(@"Last Name: %@", [PSPropertyFetcher fetchLastnameForPersonID:i]);
    NSLog(@"Organization: %@", [PSPropertyFetcher fetchOrganizationForPersonID:i]);
    NSLog(@"Department: %@", [PSPropertyFetcher fetchDepartmentForPersonID:i]);        
    NSLog(@"Job Title: %@\n\n", [PSPropertyFetcher fetchJobTitleForPersonID:i]);        
}

This works only partly; this is the output:

2012-06-27 10:37:30.094 Guess Who![80103:f803] Property Fetchers Test

2012-06-27 10:37:30.108 Guess Who![80103:f803] First Name: Jod

2012-06-27 10:37:30.114 Guess Who![80103:f803] Middle Name: Bob

2012-06-27 10:37:30.118 Guess Who![80103:f803] Last Name: Satson

2012-06-27 10:37:30.122 Guess Who![80103:f803] Organization: Johnson and Johnson

2012-06-27 10:37:30.125 Guess Who![80103:f803] Department: NULL

2012-06-27 10:37:30.128 Guess Who![80103:f803] Job Title: NULL


2012-06-27 10:37:30.136 Guess Who![80103:f803] First Name: Shemairan

2012-06-27 10:37:30.166 Guess Who![80103:f803] Middle Name: Daitran

2012-06-27 10:37:30.179 Guess Who![80103:f803] Last Name: Catairan

2012-06-27 10:37:30.184 Guess Who![80103:f803] Organization: Shmairo and Co.

2012-06-27 10:37:30.188 Guess Who![80103:f803] Department: NULL

2012-06-27 10:37:30.193 Guess Who![80103:f803] Job Title: NULL


2012-06-27 10:37:30.202 Guess Who![80103:f803] First Name: Alex

2012-06-27 10:37:30.207 Guess Who![80103:f803] Middle Name: John

2012-06-27 10:37:30.213 Guess Who![80103:f803] Last Name: Corn

2012-06-27 10:37:30.219 Guess Who![80103:f803] Organization: Apple

2012-06-27 10:37:30.225 Guess Who![80103:f803] Department: NULL

2012-06-27 10:37:30.230 Guess Who![80103:f803] Job Title: NULL

In the iOS Simulator Contacts application, I made sure to fill out every field for each contact, but for some reason, the "Department" and "Job Title" fields are not printing correctly.

Basically, I'm wondering what's wrong with my "Job Title" and "Department" fetcher methods.

Thanks in advance!

like image 878
pasawaya Avatar asked Mar 26 '26 15:03

pasawaya


1 Answers

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.)

like image 128
john.k.doe Avatar answered Mar 29 '26 05:03

john.k.doe