2013-05-13 10 views
8

私のアプリケーションでは、Crashlyticsはユーザーからクラッシュレポートを収集するために使用されます。ユーザーからのクラッシュレポートが1つあります。おそらくユーザーの連絡先情報に依存しています。私は彼/彼女の連絡先に何があるかわからないので、クラッシュを再現することはできません。どのような人がこの状況について考えていますか?ユーザーがアドレス帳にアクセスしたときのクラッシュレポート

com.apple.root.default-priority Crashed 
0 CoreFoundation CFStringCreateCopy + 13 
1 AppSupport CPSqliteDatabaseCreateWithPath + 36 
2 AppSupport CPSqliteDatabaseCreateWithPath + 36 
3 AppSupport CPRecordStoreGetDatabase + 16 
4 AppSupport _getReaderConnection + 10 
5 AppSupport CPRecordStoreProcessQueryWithBindBlock + 22 
6 AppSupport CPRecordStoreCopyAllInstancesOfClassWhereWithBindBlock + 98 
7 AddressBook  ABCCopyArrayOfAllPeopleInSourceWithSortOrdering + 244 
8 SeeYouKee PhoneNumberInputViewController.m line 538-[PhoneNumberInputViewController dofetchContacts:] 
9 AddressBook  __37-[ABTCC accessRequestWithCompletion:]_block_invoke_0 + 26 
10 TCC  __TCCAccessRequest_block_invoke_038 + 316 
11 ... libxpc.dylib _xpc_connection_call_reply + 26 
12 libdispatch.dylib _dispatch_root_queue_drain + 278 
13 libdispatch.dylib _dispatch_worker_thread2 + 92 
14 libsystem_c.dylib _pthread_wqthread + 360 

8 SeeYouKee PhoneNumberInputViewController.m line 538-[PhoneNumberInputViewController dofetchContacts:] ためのコードは次のとおり

NSArray *contactsInAddressBook = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByLastName)); 

EDIT 1

-(void)dofetchContacts:(ABAddressBookRef)addressBook{ 
NSMutableArray *contactMutArr = [NSMutableArray array]; 
NSMutableString *mStrOfContacts = [NSMutableString string]; 

NSArray *contactsInAddressBook = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByLastName)); 

if (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatLastNameFirst) { 

    for (id aPerson in contactsInAddressBook) { 

     ABRecordRef person = (__bridge ABRecordRef)(aPerson); 

     ABMultiValueRef phoneMultiValue = ABRecordCopyValue(person, kABPersonPhoneProperty); 
     ABMultiValueRef emailMultiValue = ABRecordCopyValue(person, kABPersonEmailProperty); 
     int countPhone = 0; 
     int countEmail = 0; 
     NSMutableArray *phoneStrArr; 
     NSMutableArray *emailStrArr; 

     if (phoneMultiValue != NULL) { 
      countPhone = ABMultiValueGetCount(phoneMultiValue); 
     } 

     if (emailMultiValue != NULL) { 
      countEmail = ABMultiValueGetCount(emailMultiValue); 
     } 

     if (countEmail>0) { 
      emailStrArr = [NSMutableArray array]; 
      for (int i = 0; i < countEmail; i++) { 
       CFStringRef anEmailCF = ABMultiValueCopyValueAtIndex(emailMultiValue, i); 
       NSString *anEmail = (__bridge NSString *)anEmailCF; 
       [emailStrArr addObject:anEmail]; 
       if (anEmailCF != NULL)CFRelease(anEmailCF); 
      } 
     } 

     if (countPhone > 0) { 

      phoneStrArr = [NSMutableArray array]; 
      for (int i = 0; i < countPhone; i++) { 
       CFStringRef anPhoneCF = ABMultiValueCopyValueAtIndex(phoneMultiValue, i); 
       NSString *anPhone = (__bridge NSString *)anPhoneCF; 
       NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@""] invertedSet]; 
       NSString *anPhonePureNumber = [[anPhone componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; 
       [phoneStrArr addObject:anPhonePureNumber]; 
       if (anPhoneCF != NULL)CFRelease(anPhoneCF); 
      } 

     } 
     //    if (arrRefOfEmails != NULL)CFRelease(arrRefOfEmails); 


     CFStringRef lastNameMultiValueCF = ABRecordCopyValue(person, kABPersonLastNameProperty); 
     CFStringRef firstNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonFirstNameProperty); 
     CFStringRef middleNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonMiddleNameProperty); 
     NSString *lastNameMultiValue = (__bridge NSString *)lastNameMultiValueCF; 
     NSString *firstNmaeMultiValue = (__bridge NSString *)firstNmaeMultiValueCF; 
     NSString *middleNmaeMultiValue = (__bridge NSString *)middleNmaeMultiValueCF; 

     NSString *name = [NSString stringWithFormat:@"%@%@%@",(![lastNameMultiValue length])[email protected]"":lastNameMultiValue, (![middleNmaeMultiValue length])[email protected]"":middleNmaeMultiValue, (![firstNmaeMultiValue length])[email protected]"":firstNmaeMultiValue]; 

     if (lastNameMultiValueCF != NULL)CFRelease(lastNameMultiValueCF); 
     if (firstNmaeMultiValueCF != NULL)CFRelease(firstNmaeMultiValueCF); 
     if (middleNmaeMultiValueCF != NULL)CFRelease(middleNmaeMultiValueCF); 
     CFDataRef anAvatarCF = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail); 

     NSData *anAvatarData = (__bridge NSData *)anAvatarCF; 
     UIImage *anAvatar = [UIImage imageWithData:anAvatarData]; 

     if (anAvatarCF != NULL)CFRelease(anAvatarCF); 

     NSDictionary *aPersonDict = [NSDictionary dictionaryWithObjectsAndKeys:name, @"name", [phoneStrArr componentsJoinedByString:@"; "], @"phoneNumber", [emailStrArr componentsJoinedByString:@"; "], @"email", anAvatar, @"avatar", nil]; 
     [contactMutArr addObject:aPersonDict]; 

     NSLog(@"------phoneStrArr :%@",phoneStrArr); 
     NSString *enPhoneNumber = @""; 
     if (phoneStrArr) { 
      enPhoneNumber = [EncryptWithMD5 encryptWithMD5: [phoneStrArr componentsJoinedByString:@"; "]]; 
     } 
     [mStrOfContacts appendString:enPhoneNumber]; 
     [mStrOfContacts appendString:@", "]; 
     if (phoneMultiValue != NULL)CFRelease(phoneMultiValue); 
     if (emailMultiValue != NULL)CFRelease(emailMultiValue); 

    } 

}else{ 

    for (id aPerson in contactsInAddressBook) { 
     ABRecordRef person = (__bridge ABRecordRef)(aPerson); 
     ABMultiValueRef phoneMultiValue = ABRecordCopyValue(person, kABPersonPhoneProperty); 
     ABMultiValueRef emailMultiValue = ABRecordCopyValue(person, kABPersonEmailProperty); 
     int countEmail = 0; 
     NSMutableArray *emailStrArr; 
     NSMutableArray *phoneStrArr; 

     if (emailMultiValue != NULL) { 
      countEmail = ABMultiValueGetCount(emailMultiValue); 
     } 

     if (countEmail>0) { 
      emailStrArr = [NSMutableArray array]; 
      for (int i = 0; i < countEmail; i++) { 
       CFStringRef anEmailCF = ABMultiValueCopyValueAtIndex(emailMultiValue, i); 
       NSString *anEmail = (__bridge NSString *)anEmailCF; 
       [emailStrArr addObject:anEmail]; 
       if (anEmailCF != NULL)CFRelease(anEmailCF); 
      } 
     } 

     int count = ABMultiValueGetCount(phoneMultiValue); 

     if (count > 0) { 
      phoneStrArr = [NSMutableArray array]; 
      for (int i = 0; i < count; i++) { 
       CFStringRef anPhoneCF = ABMultiValueCopyValueAtIndex(phoneMultiValue, i); 
       NSString *anPhone = (__bridge NSString *)anPhoneCF; 
       NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@""] invertedSet]; 
       NSString *anPhonePureNumber = [[anPhone componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; 
       [phoneStrArr addObject:anPhonePureNumber]; 
       if (anPhoneCF != NULL)CFRelease(anPhoneCF); 
      } 
     } 

     CFStringRef lastNameMultiValueCF = ABRecordCopyValue(person, kABPersonLastNameProperty); 
     CFStringRef firstNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonFirstNameProperty); 
     CFStringRef middleNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonMiddleNameProperty); 
     NSString *lastNameMultiValue = (__bridge NSString *)lastNameMultiValueCF; 
     NSString *firstNmaeMultiValue = (__bridge NSString *)firstNmaeMultiValueCF; 
     NSString *middleNmaeMultiValue = (__bridge NSString *)middleNmaeMultiValueCF; 

     NSString *name = [NSString stringWithFormat:@"%@%@%@", (![firstNmaeMultiValue length])[email protected]"":firstNmaeMultiValue, (![middleNmaeMultiValue length])[email protected]"":middleNmaeMultiValue,(![lastNameMultiValue length])[email protected]"":lastNameMultiValue]; 

     if (lastNameMultiValueCF != NULL)CFRelease(lastNameMultiValueCF); 
     if (firstNmaeMultiValueCF != NULL)CFRelease(firstNmaeMultiValueCF); 
     if (middleNmaeMultiValueCF != NULL)CFRelease(middleNmaeMultiValueCF); 

     CFDataRef anAvatarCF = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail); 

     NSData *anAvatarData = (__bridge NSData *)anAvatarCF; 
     UIImage *anAvatar = [UIImage imageWithData:anAvatarData]; 

     if (anAvatarCF != NULL)CFRelease(anAvatarCF); 

     NSDictionary *aPersonDict = [NSDictionary dictionaryWithObjectsAndKeys:name, @"name", [phoneStrArr componentsJoinedByString:@"; "], @"phoneNumber", [emailStrArr componentsJoinedByString:@"; "], @"email", anAvatar, @"avatar", nil]; 
     [contactMutArr addObject:aPersonDict]; 

     NSString *enPhoneNumber = [EncryptWithMD5 encryptWithMD5: [phoneStrArr componentsJoinedByString:@"; "]]; 
     [mStrOfContacts appendString:enPhoneNumber]; 
     [mStrOfContacts appendString:@", "]; 

     if (phoneMultiValue != NULL)CFRelease(phoneMultiValue); 
     if (emailMultiValue != NULL)CFRelease(emailMultiValue); 

    } 


} 
self.contactArr = [[NSArray alloc] initWithArray: contactMutArr]; 
strOfContacts = [NSString stringWithString:mStrOfContacts]; 
} 

編集2

-(void)beginFetchContacts{ 
// Request authorization to Address Book 
ABAddressBookRef addressBookRef = NULL; 

if (ABAddressBookRequestAccessWithCompletion) { 
    CFErrorRef *aError=nil; 
    addressBookRef = ABAddressBookCreateWithOptions(NULL, aError); 

    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) { 
     ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) { 
      // First time access has been granted, add the contact 
      if (granted) { 
       [self dofetchContacts:addressBookRef]; 
      }else{ 
       //    [self alertActionSwitchOnTheContactsAccess]; 
       [self buttonCancelPressed:nil]; 
      } 
     }); 
    } 
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) { 
     // The user has previously given access, add the contact 
     [self dofetchContacts:addressBookRef]; 
    } 
}else{ 
    addressBookRef = ABAddressBookCreate(); 
    [self dofetchContacts:addressBookRef]; 
} 

if (addressBookRef != NULL)CFRelease(addressBookRef); 
} 
+0

可能であれば、アドレス帳から連絡先を取得している場所でソースコードを提供してください。数日前にもクラッシュしていましたが、それはCore Foundationオブジェクトの間違ったリリースであることが判明しました。 –

+0

@Deepesh更新を確認してください。 –

+0

@Deepesh私は理由があると思った。これはABPersonGetCompositeNameFormatにあります。 –

答えて

5

それはあなたがABAddressBookCreateWithOptionsを呼んでいることだろう()、および/またはABAddressBookRequestAccessWithCompletion()あなたがABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering()を呼び出している場所とは別のスレッドで?

AppleのAPIドキュメントから、次の点に注意してください。

完了ハンドラを任意のキューに呼ばれています。アプリ全体でアドレス帳を使用している場合は、スレッドセーフな操作が確実に行われるように、そのアドレス帳のすべての使用が単一のキューに確実に送信されるようにする必要があります。

出典:

はまた、あなたが途中であなたがABAddressBookCreateWithOptionsから戻ったABAddressBookRefを()を放出していないことを確認するチェックしhttp://developer.apple.com/library/ios/#documentation/AddressBook/Reference/ABAddressBookRef_iPhoneOS/Reference/reference.html。 ABAddressBookRequestAccessWithCompletion()は非同期であることに注意してください。

+0

私は投稿を編集していますが、問題はif(addressBookRef!= NULL)CFRelease(addressBookRef); –

6

私は

ABAddressBookはスレッドセーフではありませんので、あなたは、2つの異なるスレッド、 からそれを呼び出す場合に例外をスローすると、アプリがクラッシュクラッシュしたスレッドは「com.apple.root.default-優先」であることがわかり

DISPATCH_QUEUE_PRIORITY_DEFAULTはシリアルキューではないため、常にDISPATCH_QUEUE_PRIORITY_DEFAULTへのコールをディスパッチしても、2つの異なるスレッドで実行される可能性があります。このキューにアドレス帳に

dispatch_queue_t abQueue = dispatch_queue_create("myabqueue", DISPATCH_QUEUE_SERIAL); 
dispatch_set_target_queue(abQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); 

を派遣することを忘れないでください(同期または非同期)すべてのコール:

使用これはDISPATCH_QUEUE_PRIORITY_DEFAULTする派遣シリアルキューを作成します。

EDIT:

あなたが機能ABAddressBookRequestAccessWithCompletionに渡さ完了ハンドラブロックにdofetchContactsを呼び出しているように見えます。この呼び出しをメインスレッドにディスパッチしてください!

ドキュメントは言う:

完了ハンドラを任意のキューに呼ばれています。アプリ全体で がアドレス帳を使用している場合は、 を使用して、そのアドレス帳のすべての使用が確実に正しいキューにディスパッチされ、スレッドセーフな操作が確実に行われるようにしてください。

+0

実際に "dofetchContacts:"がメインスレッドで実行されます。 "com.apple.root.default-priority"はCrashLyticsのメモです。 –

+1

いいえ、実際にこのコードはメインスレッドでは実行されません。バックグラウンドキュー。 – Felix

0
- (IBAction)btn_addprofile:(id)sender 
{ 
    // creating the picker 
    ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init]; 
    // place the delegate of the picker to the controll 
    picker.peoplePickerDelegate = self; 

    // showing the picker 

    app.appstart=0; 
    [self presentModalViewController:picker animated:YES]; 
    // releasing 
    [picker release]; 
} 

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker 
{ 
    // assigning control back to the main controller 
    [self dismissModalViewControllerAnimated:YES]; 
} 

- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { 

    add_profile_screen *viewcontroller=[[add_profile_screen alloc]initWithNibName:@"add_profile_screen" bundle:nil]; 



    // setting the first name 

    NSString *str_f =(NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
    NSString *str_l=(NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); 

    NSLog(@"%@",str_f); 
    NSLog(@"%@",str_l); 

    if([str_f isEqualToString:@""] || [str_l isEqualToString:@""] || !str_f || !str_l) 
    { 
     if([str_f isEqualToString:@""] || !str_f) 
     { 
      viewcontroller.strfirstname=[NSString stringWithFormat:@"%@",str_l]; 
     } 
     else 
     { 
      viewcontroller.strfirstname=[NSString stringWithFormat:@"%@ ",str_f]; 
     } 
    } 
    else 
    { 
     viewcontroller.strfirstname=[NSString stringWithFormat:@"%@ %@",str_f,str_l]; 
    } 

    // viewcontroller.strname=[NSString stringWithFormat:@"%@",(NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty)]; 



    ABMutableMultiValueRef multi = ABRecordCopyValue(person, kABPersonEmailProperty); 
    if (ABMultiValueGetCount(multi) > 0) 
    { 
     // collect all emails in array 
     // for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) 
     for (CFIndex i = 0; i <1; i++) 
     { 
      CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i); 
      viewcontroller.strlastname= (NSString *)emailRef; 
      CFRelease(emailRef); 
     } 
    } 

    // setting the number 
    ABMultiValueRef multi1 = ABRecordCopyValue(person, kABPersonPhoneProperty); 
    viewcontroller.strnumber=[NSString stringWithFormat:@"%@",(NSString*)ABMultiValueCopyValueAtIndex(multi1, 0)]; 
    NSLog(@"%@",viewcontroller.strnumber); 


    [self.navigationController pushViewController:viewcontroller animated:YES]; 
    [viewcontroller release]; 


     // remove the controller 
    [self dismissModalViewControllerAnimated:YES]; 

    return NO; 
} 

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier 
{ 
    return NO; 
} 
関連する問題