我在解决随机崩溃时遇到问题:有时会崩溃/有时不会。执行 ABAddressBookSave 时根据EXC_BAD_ACCESS !,我应该将 multivalueref 用于正确的值,
日期、地址、电子邮件、电话:都被视为 multiValueRef。
参考代码:
CFErrorRef error = NULL;
ABRecordRemoveValue (record,kABPersonFirstNameProperty,&error);
ABRecordRemoveValue(record, kABPersonLastNameProperty,&error);
ABRecordRemoveValue(record, kABPersonOrganizationProperty,&error);
ABRecordRemoveValue(record, kABPersonPrefixProperty,&error);
ABRecordRemoveValue(record, kABPersonSuffixProperty,&error);
ABRecordRemoveValue(record, kABPersonNicknameProperty,&error);
ABRecordRemoveValue(record, kABPersonMiddleNameProperty,&error);
ABRecordRemoveValue(record,kABPersonDepartmentProperty,&error);
ABRecordRemoveValue(record,kABPersonJobTitleProperty,&error);
ABRecordRemoveValue(record,kABPersonNoteProperty,&error);
ABRecordRemoveValue(record,kABPersonBirthdayProperty,&error);
ABRecordRemoveValue(record,kABPersonAddressProperty,&error);
ABRecordRemoveValue(record,kABPersonEmailProperty,&error);
ABRecordRemoveValue(record,kABPersonPhoneProperty,&error);
bool success = false;
string m_strDisplayName = item->getDisplayName();
string m_strFirstName = item->getFirstName();
string m_strLastName = item->getLastName();
string m_strMiddleName = item->getMiddleName();
string m_strAddress = item->getAddress();
string m_strHomeAddr = item->getHomeAddress();
string m_strWorkAddress = item->getWorkAddress();
string m_strCompany = item->getCompany();
string m_strTitle = item->getTitle();
string m_strPhoto = item->getPhoto();
string m_strNotes = item->getNotes();
string m_strPrefix = item->getPrefix();
string m_strSuffix = item->getSuffix();
string m_strNickName = item->getNickName();
string m_strDepartment = item->getDepartment();
string m_strBirthDay = item->getBirthDay();
string m_strAnniversary = item->getAnniversary();
CFStringRef c1 = NULL;
CFStringRef c2 = NULL;
CFStringRef c3 = NULL;
CFStringRef c4 = NULL;
CFStringRef c5 = NULL;
CFStringRef c6 = NULL;
CFStringRef c7 = NULL;
CFStringRef c8 = NULL;
CFStringRef c9 = NULL;
CFStringRef c10 = NULL;
NSDateComponents *components1 = nil;
NSDateComponents *components2 = nil;
if (m_strBirthDay.length()!=0) {
U_STRING bdayyear =m_strBirthDay.substr (0,4);
U_STRING bdaymonth = m_strBirthDay.substr(4,2);
U_STRING bdayday = m_strBirthDay.substr(6, 2);
components1 = [[NSDateComponents alloc] init];
[components1 setDay:STRING_TO_INT(bdayday)];
[components1 setMonth:STRING_TO_INT(bdaymonth)];
[components1 setYear:STRING_TO_INT(bdayyear)];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *bday = [gregorian dateFromComponents:components1];
c10 = CFStringCreateWithCString(kCFAllocatorDefault,m_strBirthDay.c_str(),kCFStringEncodingUTF8);
ABRecordSetValue(record, kABPersonBirthdayProperty,bday, &error);
}
if (m_strAnniversary.length()!=0) {
U_STRING anniyear =m_strAnniversary.substr (0,4);
U_STRING annimonth = m_strAnniversary.substr(4,2);
U_STRING anniday = m_strAnniversary.substr(6, 2);
components2 = [[NSDateComponents alloc] init];
[components2 setDay:STRING_TO_INT(anniday)];
[components2 setMonth:STRING_TO_INT(annimonth)];
[components2 setYear:STRING_TO_INT(anniyear)];
NSCalendar *gregorian1 = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *anni = [gregorian1 dateFromComponents:components2];
ABMutableMultiValueRef multiDate = ABMultiValueCreateMutable(kABPersonDateProperty);
ABMultiValueAddValueAndLabel(multiDate,anni,kABPersonAnniversaryLabel, NULL);
ABRecordSetValue(record, kABPersonDateProperty, multiDate,&error);
}
if(m_strPhoto.length()!=0)
{
CFDataRef pho = CFDataCreate( NULL, (const UInt8*) m_strPhoto.data(), m_strPhoto.size() );
ABPersonSetImageData (record,pho,&error);
}
string chome=m_strHomeAddr;
string cwork=m_strWorkAddress;
NSString *nhome,*nwork;
nhome=[[NSString alloc]initWithCString:chome.c_str() encoding:NSUTF8StringEncoding];
nwork=[[NSString alloc]initWithCString:cwork.c_str() encoding:NSUTF8StringEncoding];
NSArray *ahome = [nhome componentsSeparatedByString:@";"];
NSArray *awork = [nwork componentsSeparatedByString:@";"];
NSMutableDictionary *addressDictionary = nil;
ABMutableMultiValueRef multiAddress =ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
if([ahome count]>=2 &&([[ahome objectAtIndex:2] length] !=0 ||[[ahome objectAtIndex:3] length] !=0 ||[[ahome objectAtIndex:4] length] !=0 ||[[ahome objectAtIndex:5] length] !=0 ||[[ahome objectAtIndex:6] length] !=0 ))
{
addressDictionary = [[NSMutableDictionary alloc] init];
if([[ahome objectAtIndex:2] length] !=0){
[addressDictionary setObject:[ahome objectAtIndex:2] forKey:(NSString *) kABPersonAddressStreetKey];
}
if([ahome count]>3 && [[ahome objectAtIndex:3] length] !=0){
[addressDictionary setObject:[ahome objectAtIndex:3] forKey:(NSString *)kABPersonAddressCityKey];
}
if([ahome count]>4 && [[ahome objectAtIndex:4] length] !=0){
[addressDictionary setObject:[ahome objectAtIndex:4] forKey:(NSString *)kABPersonAddressStateKey];
}
if([ahome count]>5 && [[ahome objectAtIndex:5] length] !=0){
[addressDictionary setObject:[ahome objectAtIndex:5] forKey:(NSString *)kABPersonAddressZIPKey];
}
if([ahome count]>6 && [[ahome objectAtIndex:6] length] !=0){
[addressDictionary setObject:[ahome objectAtIndex:6] forKey:(NSString *)kABPersonAddressCountryKey];
}
ABMultiValueAddValueAndLabel(multiAddress, addressDictionary, kABHomeLabel, NULL);
}
NSMutableDictionary *addressDictionary1 = nil;
if([awork count]>=2&&([[awork objectAtIndex:2] length] !=0 ||[[awork objectAtIndex:3] length] !=0 ||[[awork objectAtIndex:4] length] !=0 ||[[awork objectAtIndex:5] length] !=0 ||[[awork objectAtIndex:6] length] !=0 ))
{
addressDictionary1 = [[NSMutableDictionary alloc] init];
if([[awork objectAtIndex:2] length] !=0)
[addressDictionary1 setObject:[awork objectAtIndex:2] forKey:(NSString *) kABPersonAddressStreetKey];
if([[awork objectAtIndex:3] length] !=0)
[addressDictionary1 setObject:[awork objectAtIndex:3] forKey:(NSString *)kABPersonAddressCityKey];
if([[awork objectAtIndex:4] length] !=0)
[addressDictionary1 setObject:[awork objectAtIndex:4] forKey:(NSString *)kABPersonAddressStateKey];
if([[awork objectAtIndex:5] length] !=0)
[addressDictionary1 setObject:[awork objectAtIndex:5] forKey:(NSString *)kABPersonAddressZIPKey];
if([[awork objectAtIndex:6] length] !=0)
[addressDictionary1 setObject:[awork objectAtIndex:6] forKey:(NSString *)kABPersonAddressCountryKey];
ABMultiValueAddValueAndLabel(multiAddress, addressDictionary1, kABWorkLabel, NULL);
}
success = ABRecordSetValue(record, kABPersonAddressProperty, multiAddress,&error);
if (addressDictionary) [addressDictionary release];
if (addressDictionary1) [addressDictionary1 release];
//setting Emails
vector<U_STRING> emails = item->getEmails();
vector<U_UINT32> emailAttrs = item->getEmailAttrs();
NSString *em = NULL;
CFStringRef c1pe = NULL;
string s="Primary Email";
c1pe=CFStringCreateWithCString(kCFAllocatorDefault,s.c_str(),kCFStringEncodingUTF8);
ABMutableMultiValueRef multiEmail = ABMultiValueCreateMutable(kABMultiStringPropertyType);
if (emails.size()>0) {
for (int i = 0; i < emails.size(); i++) {
string attr = "";
string email =emails.at(i);
if (email.length() == 0) {
continue;
}
em = [NSString stringWithCString:email.c_str() encoding:NSUTF8StringEncoding];
int emailAttr = emailAttrs.at(i);
if ((emailAttr & item->ATTR_HOME) != 0) {
attr += ";HOME";
ABMultiValueAddValueAndLabel(multiEmail, em, kABHomeLabel, NULL);
}
else if ((emailAttr & item->ATTR_WORK) != 0) {
attr += ";WORK";
ABMultiValueAddValueAndLabel(multiEmail, em, kABWorkLabel, NULL);
}
else if ((emailAttr & item->ATTR_NONE) != 0) {
attr += ";OTHER";
ABMultiValueAddValueAndLabel(multiEmail, em, kABOtherLabel, NULL);
}
else {
ABMultiValueAddValueAndLabel(multiEmail,em,c1pe, NULL);
}
}
ABRecordSetValue(record, kABPersonEmailProperty, multiEmail,&error);
}
//setting Phones
vector<U_STRING> phoneNumbers = item->getPhoneNumbers();
vector<U_UINT32> phoneNumberAttrs = item->getPhoneNumberAttrs();
NSString *ph = NULL;
CFStringRef c1hp = NULL;
c1hp=CFStringCreateWithCString(kCFAllocatorDefault,s.c_str(),kCFStringEncodingUTF8);
CFStringRef c1wp = NULL;
c1wp=CFStringCreateWithCString(kCFAllocatorDefault,s.c_str(),kCFStringEncodingUTF8);
ABMutableMultiValueRef multiPhone = ABMultiValueCreateMutable(kABMultiStringPropertyType);
if (phoneNumbers.size()>0)
{
for (int i = 0; i < phoneNumbers.size(); i++) {
string attr = "";
string phoneNumber =phoneNumbers.at(i);
if (phoneNumber.length() == 0) {
continue;
}
ph=[NSString stringWithCString:phoneNumber.c_str() encoding:NSUTF8StringEncoding];
int phoneAttr = phoneNumberAttrs.at(i);
if ((phoneAttr & item->ATTR_PAGER) != 0) {
attr += ";PAGER";
if ((phoneAttr & item->ATTR_HOME) != 0) {
attr += ";HOME";
ABMultiValueAddValueAndLabel(multiPhone,ph,kABPersonPhonePagerLabel, NULL);
}else if ((phoneAttr & item->ATTR_WORK) != 0) {
attr += ";WORK";
ABMultiValueAddValueAndLabel(multiPhone,ph,kABPersonPhonePagerLabel, NULL);
}
}
else if ((phoneAttr & item->ATTR_FAX) != 0) {
attr += ";FAX";
if ((phoneAttr & item->ATTR_HOME) != 0) {
attr += ";HOME";
ABMultiValueAddValueAndLabel(multiPhone,ph,kABPersonPhoneHomeFAXLabel, NULL);
}else if ((phoneAttr & item->ATTR_WORK) != 0) {
attr += ";WORK";
ABMultiValueAddValueAndLabel(multiPhone,ph,kABPersonPhoneWorkFAXLabel, NULL);
}
}
else if ((phoneAttr & item->ATTR_MOBILE) != 0) {
attr += ";CELL";
if ((phoneAttr & item->ATTR_HOME) != 0) {
attr += ";HOME";
string s="Mobile (Home)";
ABMultiValueAddValueAndLabel(multiPhone,ph,c1hp, NULL);
}else if ((phoneAttr & item->ATTR_WORK) != 0) {
attr += ";WORK";
string s="Mobile (Work)";
ABMultiValueAddValueAndLabel(multiPhone,ph,c1wp, NULL);
}
else {
ABMultiValueAddValueAndLabel(multiPhone,ph,kABPersonPhoneMobileLabel, NULL);
}
}
else {
attr += ";VOICE";
if ((phoneAttr & item->ATTR_HOME) != 0) {
attr += ";HOME";
ABMultiValueAddValueAndLabel(multiPhone,ph, kABHomeLabel, NULL);
}else if ((phoneAttr & item->ATTR_WORK) != 0) {
attr += ";WORK";
ABMultiValueAddValueAndLabel(multiPhone,ph, kABWorkLabel, NULL);
}
else {
ABMultiValueAddValueAndLabel(multiPhone,ph,kABPersonPhoneMainLabel, NULL);
}
}
}
ABRecordSetValue(record, kABPersonPhoneProperty, multiPhone,&error);
}
//saving to address book
if(ABAddressBookAddRecord(addressBook, record, &error)){
success = ABAddressBookSave(addressBook, &error);//EXC_BAD_EXCESS only sometimes(may be only for some contacts or their property. I am not sure)
if (error !=NULL) {
NSLog(@"error:%@",error);
}
}
注意:仔细检查后,我发现 ABAddressBookSave 是线程运行被卡住的地方,而其他线程却发生了崩溃,请参阅下面的堆栈跟踪:
但这并不总是相同的。
谁能发现这段代码有什么问题?请帮忙。
编辑:我评论了这个方法中的所有代码,只是写道:
if(ABAddressBookAddRecord(addressBook, record, &error)){
success = ABAddressBookSave(addressBook, &error);//EXC_BAD_EXCESS
if (error !=NULL) {
NSLog(@"error:%@",error);
}
}
它仍然与 bt 崩溃:
我怀疑这是一些线程问题。如果有知情人士可以评论并确认这一点,将有很大帮助!