CFStrings and storing them into models, related topics

Posted by Jasconius on Stack Overflow See other posts from Stack Overflow or by Jasconius
Published on 2010-05-10T17:18:12Z Indexed on 2010/05/10 17:34 UTC
Read the original article Hit count: 207

I have a very frustrating issue that I believe involves CFStringRef and passing them along to custom model properties.

The code is pretty messy right now as I am in a debug state, but I will try to describe the problem in words as best as I can.

I have a custom model, User, which for irrelevant reasons, I am storing CF types derived from the Address Book API into. Examples include: Name, email as NSStrings. I am simply retrieving the CFStringRef value from the AddressBook API and casting as a string, whereupon I assign to the custom model instance and then CFRelease the string.

These NSString properties are set as (nonatomic, retain).

I then store this model into an NSArray, and I use this Array as a datasource for a UITableView

When accessing the object in the cellForRowAtIndexPath, I get a memory access error.

When I do a Debug, I see that the value for this datasource array appears at first glance to be corrupted. I've seen strange values assigned to it, including just plain strings, such as one that I fed to an NSLog function in earlier in the method.

So, the thing that leads me to believe that this is Core Foundation related is that I am executing this exact same code, in the same class even, on non-Address Book data, in fact, just good old JSON parsed strings, which produce true Cocoa NSStrings, that I follow the same exact steps to create the datasource array. This code works fine.

I have a feeling that my (retain) property declaration and/or my [stringVar release] in my custom model dealloc method may be causing memory problems (since it is my understanding that you shouldn't call a Cocoa retain or release on a CF object).

Here is the code. I know some of this is super-roundabout but I was trying to make things as explicit as possible for the sake of debugging.

NSMutableArray *friendUsers = [[NSMutableArray alloc] init];

int numberOfPeople = CFArrayGetCount(people);

for (int i = 0; i < numberOfPeople; i++)
{       
    ABMutableMultiValueRef emails = ABRecordCopyValue(CFArrayGetValueAtIndex(people, i), kABPersonEmailProperty);


    if (ABMultiValueGetCount(emails) > 0)
    {


        User *addressContact = [[User alloc] init];

        NSString *firstName = (NSString *)ABRecordCopyValue(CFArrayGetValueAtIndex(people, i), kABPersonFirstNameProperty);
        NSString *lastName = (NSString *)ABRecordCopyValue(CFArrayGetValueAtIndex(people, i), kABPersonLastNameProperty);

        NSLog(@"%@ and %@", firstName, lastName);

        NSString *fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];

        NSString *email = [NSString stringWithFormat:@"%@", (NSString *)ABMultiValueCopyValueAtIndex(emails, 0)];

        NSLog(@"the email: %@", email);

        [addressContact setName:fullName];          
        [addressContact setEmail:email];

        [friendUsers addObject:addressContact];

        [firstName release];
        [lastName release];
        [email release];
        [addressContact release];           
    }       

    CFRelease(emails);      
}

NSLog(@"friend count: %d", [friendUsers count]);

abFriends = [NSArray arrayWithArray:friendUsers];

[friendUsers release];

All of that works, every logging statement returns as expected. But when I use abFriends as a datasource, poof. Dead.

Is my approach all wrong? Any advice?

© Stack Overflow or respective owner

Related posts about core-foundation

Related posts about cocoa