2

ランダム クラッシュの解決に問題があります。クラッシュする場合としない場合があります。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でクラッシュしています: ここに画像の説明を入力

これはスレッドの問題であると思われます。知識のある人がこれをコメントして確認できる場合は、非常に役立ちます!

4

2 に答える 2

5

問題が発生しました: 問題を引き起こしている C++ コードがいくつかありました。strcpy(str1, str2)文字列に特別なチャーターがある関数を使用していたため、/0 で終わっていませんでした。を使用してstrncpy(str1,str2,len)解決しました。

于 2013-03-26T07:20:59.723 に答える
1

あなたのコードでは、ユーザーの許可を求める場所が表示されませんここで説明されているように、アプリが連絡先にアクセスできるようにする許可をユーザーに求めることができます

于 2013-03-23T17:42:07.190 に答える