What ABRecordCopyValue can return? (solving a bad access)

戏子无情 提交于 2019-12-19 04:07:07

问题


I'm using this simple code to get all contacts of the address book in ios 7. I have 155 contacts in my address. When i log people firstNames i obtain 34 correct names picked (apparently randomly) from my address book, 15 names null and then on item 50 a bad access crash on line

   NSString *firstNames = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty)

I tried loggin surname, or image getting no changes. I tried to avoid doing ABRecordCopyValue on null object getting no changes. I tried to execute ABRecordCopyValue on item >50 and got the same result on items from 50 to 150. What i'm doing wrong? What ABRecordCopyValue can return beside correct values and null?

+(NSArray *)getAllContactsAddress
{
CFErrorRef *error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);

// SUPPOSE access has been granted
BOOL accessGranted = true;

if (accessGranted) {
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
    ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
    NSMutableArray* items = [NSMutableArray arrayWithCapacity:nPeople];


    for (int i = 0; i < nPeople; i++)
    {
        ContactsData *contacts = [ContactsData new];

        ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);

        NSString *firstNames = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);

        NSLog(@"%@",firstNames);
    }
}

回答1:


I think (I'm actually pretty sure) the issue is that nPeople is the wrong value and doesn't match the number of entries in the allPeople array, like you assume it does. You have used a strange method of getting nPeople when CFArray already provides a straight-forward method.

I reckon this will work:

CFIndex nPeople = CFArrayGetCount(allPeople);

Also you need to check if person is non-NULL before using it:

ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
NSAssert(person, @"Non-person detected!");


来源:https://stackoverflow.com/questions/24651715/what-abrecordcopyvalue-can-return-solving-a-bad-access

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