问题
Im reading the address book contacts... everything goes well until I test a contact with no First Name ( Since I can create a contact with just an email or a phone or wathever....). The code (reduced) is this:
- (NSMutableArray *) getContactsInfo {
NSMutableArray *contactsList = [[NSMutableArray alloc] init];
localAddressBook = ABAddressBookCreate();
int contactsLength = (int)ABAddressBookGetPersonCount(localAddressBook);
if (contactsLength < 1)
return nil;
for(int currentContact=1; currentContact < (contactsLength + 1); currentContact++) {
ABRecordRef person = ABAddressBookGetPersonWithRecordID(localAddressBook,(ABRecordID) currentContact);
firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSLog(@"%@", firstName);
[contactsList addObject:firstName];
CFRelease(person);
}
return contactsList;
}
and the output I get is this:
2010-02-15 14:16:25.616 testApp[7065:207] Contact0
2010-02-15 14:16:25.618 testApp[7065:207] Contact1
2010-02-15 14:16:25.619 testApp[7065:207] Contact2
Program received signal: “EXC_BAD_ACCESS”.
I have 3 contacts with First and Last names And one created with just the last name, for test purposes.
It seems I can properly read any property such as email or address with arrays... but when a contact lacks First Name Property the app crashes.
回答1:
You are doing something very wrong in your code: you are assuming that the record IDs are sequential and starting at 1. This is not the case at all, you cannot rely on this.
What you should do instead is use ABAddressBookCopyArrayOfAllPeople
to find all records in the Address Book and then use the Core Foundation CFArray
functions to get to the individual items.
(Yes, the Address Book API in the iPhone is terrible)
回答2:
You may want to enable NSZombies to see exactly where the EXEC_BAD_ACCESS is coming from.
回答3:
To make sure, the crash is taking place within ABRecordCopyValue
and not when you try to use firstName
for the first time (which may be NULL?) Also, person
is not NULL either, correct? (In general more code in the question along with details about which line is crashing would be helpful.)
Another thing to try would be to cast person
to an ABRecord*
and use [valueForProperty][1]
; the two types are toll-free bridged and you might get a different result out of the latter (though I doubt it).
Update: Given the code you have posted you need to check that firstName
is not NULL before trying to output it via NSLog
- it is very possible ABRecordCopyValue
is simply returning NULL (representing the fact there is no first name data present for that record.) You should also check for the validity of the person
ref value itself - passing NULL in person to ABRecordCopyValue
could be the source of additional problems.
回答4:
The problem is indeed a nil first name - but not at the log statement, rather where you try to insert nil into the array. You cannot insert a nil value into an array, that causes a crash. NSLog has not flushed output to the console yet which is why you do not yet see your last log statement saying first name is nil.
Any time you get data out of the address book, check to see if the value is nil before you insert it into anything.
来源:https://stackoverflow.com/questions/2268294/kabpersonfirstnameproperty-trowing-exc-bad-access