8
votes

Rapport d'accident lorsque l'utilisateur accède au carnet d'adresses

Dans mon application, Cracklytics est utilisé pour recueillir des rapports d'accident des utilisateurs. Voici un rapport d'accident d'un utilisateur. Il s'agit éventuellement en fonction des informations sur les contacts de l'utilisateur. Je ne peux pas recréer l'accident, car je ne sais pas ce qui est dans ses contacts. Est-ce que quelqu'un a une idée de cette situation? XXX PRE>

Le code de 8 Seeyoukee PhonenumberInpuViewController.M Ligne 538- [PhonenumberInpuViewController DofetchContacts:] code> est: p> xxx pré>

EDIT 1 STRY> P>

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


9 commentaires

Si possible, vous pouvez fournir votre formulaire de code source où vous recherchez des contacts à partir du carnet d'adresses? Quelques jours de retour même que j'avais un crash et je me suis avéré être la mauvaise sortie de l'objet de base de base.


@Deepesh s'il vous plaît vérifier la mise à jour.


@Deepesh je pensais avoir la raison. C'est sur l'AbpersongetCompositNameFormat.


Ok alors finalement le problème est résolu? Puis-je savoir quel était le problème?


@Deepesh im le déboguer, une fois que je le répare, je posterai une réponse :)


@Deepesh oh, non, c'est un autre bug :(


Puis-je savoir quelle version de xcode, version iOS que vous utilisez? Existe-t-il un dispositif particulier sur lequel cette crash se produit?


@Deepesh XCode4.6, iOS6.1, iPhone3.1


@Deepesh and: xcode4.6, iOS6.1.3, iPhone4.1; xcode4.6, iOS6.1.2, iPhone5.2


3 Réponses :


6
votes

Je vois que le fil écrasé est "com.apple.root.default-priorité"

Abaddressbook n'est pas un fil de sécurité, donc si vous l'appelez de deux threads différents, Il jette une exception et bloque l'application .

Même si vous envoyez toujours vos appels à Dispatch_Queue_Priority_Default, il peut s'exécuter sur deux threads différents, car Dispatch_Queue_Priority_default n'est pas une file d'attente série.

Utilisez ceci pour créer votre file d'attente série qui dépêche de DisPatch_Quue_Priority_Default: xxx

N'oubliez pas d'envoyer (synchronisation ou async) tous vos appels pour afficher le carnet d'adresses à cette file d'attente.

EDIT:

On dirait que vous appelez DofetchContacts dans un bloc de manutention d'achèvement transmis dans la fonction abaddressbookrequestaccesswithComplettion . Assurez-vous d'envoier cet appel sur le fil principal!

La documentation indique:

Le gestionnaire d'achèvement est appelé à une file d'attente arbitraire. Si votre application utilise un carnet d'adresses dans l'application, vous êtes responsable de S'assurer que toutes les utilisations de ce carnet d'adresses sont expédiées à un seul File d'attente pour assurer une opération correcte du fil-sécurité.


2 commentaires

En fait, "DofetchContacts:" fonctionne dans le fil principal. "com.apple.root.default-priorité" est la note de Crosslytics.


Non, ce code ne fonctionne pas sur le fil principal, car le gestionnaire d'achèvement est appelé à partir d'une file d'attente de fond.



0
votes
- (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;
}

0 commentaires

5
votes

pourrait-il être que vous appelez AbaddressbookcreatewithOptions () et / ou abaddressbookRequestaccesswithCompétion () sur un fil différent de l'endroit où vous appelez AbaddressbookCopyArrayOffePeopleSourceWithSorting ()?

Veuillez noter les suivants de la documentation API d'Apple:

Le gestionnaire d'achèvement est appelé à une file d'attente arbitraire. Si votre application utilise un carnet d'adresses dans l'application, vous êtes responsable de veiller à ce que toutes les utilisations de ce carnet d'adresses soient expédiées à une file d'attente unique afin de garantir une opération correcte du fil-sécurité.

Source: http: // développeur .apple.com / bibliothèque / iOS / # documentation / adresse / référence / Abaddressbookref_iphoneos / référence / référence.html

Vous pouvez également vérifier que vous ne relâchez pas prématurément la libération prématurée de l'abaddressbookref que vous êtes revenu de AbaddressBookCreatewithOptions (). N'oubliez pas que AbaddressbookReQuestAccesswithComplettion () est asynchrone.


1 commentaires

J'ai modifier le message, peut être le problème est lié à si (adressebookref! = Null) cfrelease (adressebookref);