2013-05-13 80 views
8

在我的應用中,Crashlytics用於收集用戶的崩潰報告。這是來自用戶的一個崩潰報告。這可能取決於用戶的聯繫人信息。我不能重新創建崩潰,因爲我不知道他/她的聯繫人是什麼。有沒有人對這種情況有所瞭解?用戶訪問地址簿時的崩潰報告

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對象的錯誤版本。 – 2013-05-13 03:38:56

+0

@Deepesh請檢查更新。 – 2013-05-13 03:53:35

+0

@Deepesh我以爲我明白了理由。它在ABPersonGetCompositeNameFormat上。 – 2013-05-13 04:02:26

回答

5

難道說你在不同的線程調用ABAddressBookCreateWithOptions()和/或ABAddressBookRequestAccessWithCompletion()從你打電話ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering其中()?

請注意,從蘋果的API文檔如下:

完成處理程序被調用上的任意隊列。如果您的應用程序在整個應用程序中使用地址簿,則您有責任確保將該地址簿的所有用法分派到單個隊列,以確保線程安全正常運行。

來源:http://developer.apple.com/library/ios/#documentation/AddressBook/Reference/ABAddressBookRef_iPhoneOS/Reference/reference.html

另外,檢查,以確保你沒有過早地釋放你從ABAddressBookCreateWithOptions回來的ABAddressBookRef()。記住ABAddressBookRequestAccessWithCompletion()是異步的。

+0

我已經編輯過這個帖子,可能是有關if(addressBookRef!= NULL)的問題CFRelease(addressBookRef); – 2013-06-30 06:02:17

6

我看到崩潰線程「com.apple.root.default優先」

ABAddressBook不是線程安全的,因此,如果您從兩個不同的線程調用它, 它拋出一個異常並崩潰的應用程序

即使您總是將您的調用派遣到DISPATCH_QUEUE_PRIORITY_DEFAULT,它可能會在兩個不同的線程上運行,因爲DISPATCH_QUEUE_PRIORITY_DEFAULT不是一個串行隊列。

使用此創建一個分派到DISPATCH_QUEUE_PRIORITY_DEFAULT串行隊列:

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)); 

記住調度(同步或異步)所有的呼叫通訊錄到此隊列。

編輯:

它看起來就像你調用傳遞到函數ABAddressBookRequestAccessWithCompletion完成處理程序塊dofetchContacts。請務必在主線上發送此通話!

文檔說:

完成處理程序被調用上的任意隊列。如果您的應用 在整個應用中使用地址簿,則您需要負責 確保將該地址簿的所有用途分派到單個 隊列,以確保正確的線程安全操作。

+0

實際上「dofetchContacts:」在主線程中運行,「com.apple.root.default-priority」是CrashLytics的一個註釋 – 2013-05-24 02:31:57

+1

不,實際上這個代碼並不在主線程上運行,因爲完成處理程序是從後臺隊列。 – Felix 2013-06-28 19:39:40

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; 
}