【问题标题】:Random crash on ABAddressBookSaveABAddressBookSave 上的随机崩溃
【发布时间】:2013-03-18 14:22:29
【问题描述】:

我在解决随机崩溃时遇到问题:有时会崩溃/有时不会。根据EXC_BAD_ACCESS when executing ABAddressBookSave !,我应该使用 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 崩溃:

我怀疑这是一些 线程 问题。如果有知情人士可以评论并确认这一点,将有很大的帮助!

【问题讨论】:

  • 您的应用是否可以访问用户联系人?您的代码是否寻求用户权限?
  • attr 变量的作用是什么?你做了一个奇怪的添加。
  • @VincentZgueb 这只是一个变量......并且添加的是定义的 int MACROS
  • @yunas: 当然,否则,我将在 abaddressbookcreate 上将地址簿设为 nil
  • 对于试图保存更改的线程,您是否有单独的地址簿参考?如果不是,这可能会导致随机错误,因为您无法跨多个线程传递地址簿引用。

标签: iphone ios contacts addressbook abaddressbook


【解决方案1】:

遇到问题了: 有一些 C++ 代码造成了问题。我正在使用 strcpy(str1, str2) 函数,其中字符串有特殊的章程,因此不以 /0 结尾。使用strncpy(str1,str2,len) 解决了它。

【讨论】:

    【解决方案2】:

    在您的代码中,我没有看到您寻求用户许可的任何地方 您可以要求用户允许您的应用访问联系人,如here

    所述

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-17
      • 2013-08-23
      • 2013-04-21
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多