2014-09-30 64 views
-2

我在recorer的线程有问题,我有一个联系人列表600和6显示我以下错误。ABAddressBookRef多线程错误

线程1:EXC_BAD_ACCESS(码= 1,地址= 0x29)

是下面的代码

-(void) actualizarContactos 
{ 
    CFErrorRef *error = nil; 

    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error); 

    __block BOOL accessGranted = NO; 
    if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 
     dispatch_semaphore_t sema = dispatch_semaphore_create(0); 
     ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 
      accessGranted = granted; 
      dispatch_semaphore_signal(sema); 
     }); 
     dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 

    } 
    else { // we're on iOS 5 or older 
     accessGranted = YES; 
    } 

    if (accessGranted) { 
     //ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error); 
     ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook); 
     CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName); 
     CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); 
     // NSMutableArray* items = [NSMutableArray arrayWithCapacity:nPeople]; 

     NSMutableArray *TodosContactos = [[NSMutableArray alloc]init]; 

     //consultar numero de contactos anteriores 

     NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 

     NSString *numeroContactos = [userDefaults objectForKey:@"numeroContactos"]; 

     int numContactos = [numeroContactos intValue]; 

     //validar si hay contactos nuevos 
     if(numContactos != nPeople) 
     { 


     for (int i = 0; i < nPeople; i++) 
     { 
      // NSMutableArray *contacto = [[NSMutableArray alloc]init]; 

      ContactsData *contacts = [ContactsData new]; 

      ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i); 

      //get First Name and Last Name 

      // NSMutableArray *name = [[NSMutableArray alloc]init]; 

      if((__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty)) 
      { 
      contacts.firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
      } 
      if((__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty)) 
      { 
      contacts.lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty); 
      } 

      if (!contacts.firstName) { 
       contacts.firstName = @""; 
      } 
      if (!contacts.lastName) { 
       contacts.lastName = @""; 
      } 

      contacts.compositeName = [NSString stringWithFormat:@"%@ %@",contacts.firstName,contacts.lastName]; 


      // get contacts picture, if pic doesn't exists, show standart one 

      Boolean sw = true; 

       NSData *imgData = (__bridge_transfer NSData *)ABPersonCopyImageData(person); 
       contacts.photo = [UIImage imageWithData:imgData]; 
       if (!contacts.photo) { 
        sw = false; 
        contacts.photo = [UIImage imageNamed:@"[email protected]"]; 
      } 
      //get Phone Numbers 

       NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init]; 

      Boolean swContactoSiguiente = true; 

       ABMultiValueRef multiPhones = ABRecordCopyValue(person, kABPersonPhoneProperty); 
       for(CFIndex i=0;i<ABMultiValueGetCount(multiPhones);i++) 
       { 

        CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(multiPhones, i); 
        NSString *phoneNumber = (__bridge_transfer NSString *) phoneNumberRef; 

        //prueba 
        // NSLog([NSString stringWithFormat:@"name: %@ tel: %@",contacts.compositeName,phoneNumbers]); 

        if(![phoneNumber hasPrefix:@"+"] && ![phoneNumber hasPrefix:@"00"] && ![phoneNumber hasPrefix:@"011"]) 
        { 
         swContactoSiguiente = true; 
        } 
        else 
        { 
         swContactoSiguiente = false; 
         [phoneNumbers addObject:phoneNumber]; 
        } 



       } 

      if(swContactoSiguiente) 
      { 
       continue; 
      } 



      contacts.phones = phoneNumbers; 



      //get Contact email 

       NSMutableArray *contactEmails = [NSMutableArray new]; 
       ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty); 

       for (CFIndex i=0; i<ABMultiValueGetCount(multiEmails); i++) { 
        CFStringRef contactEmailRef = ABMultiValueCopyValueAtIndex(multiEmails, i); 
       NSString *contactEmail = (__bridge_transfer NSString *)contactEmailRef; 

      [contactEmails addObject:contactEmail]; 
      // NSLog(@"All emails are:%@", contactEmails); 

       } 

      // [contacts setEmails:contactEmails]; 
      contacts.emails = contactEmails; 



      //guardar en CoreData 

      if(contacts.phones.count != 0) 
      { 
       contacts.phone = [self deleteSpace:contacts.phones[0]]; 
      } 

      //se valida existencia del phone en la base de datos 
      if([self consultarTelefono:contacts.phone]) 
      { 

      AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 

      NSManagedObjectContext *context = [appDelegate managedObjectContext]; 
      NSManagedObject *newContact; 
      newContact = [NSEntityDescription insertNewObjectForEntityForName:@"Contacts" inManagedObjectContext:context]; 

      [newContact setValue: contacts.compositeName forKey:@"compositeName"]; 
      [newContact setValue: contacts.firstName forKey:@"firstName"]; 
      [newContact setValue: contacts.lastName forKey:@"lastName"]; 
      [newContact setValue: contacts.phone forKey:@"phone"]; 

      NSNumber *fv = [NSNumber numberWithBool:false]; 
      [newContact setValue:fv forKey:@"favorite"]; 
      if(sw) 
      { 
      [newContact setValue: imgData forKey:@"photo"]; 
      } 


      NSError *error; 
      [context save:&error]; 




      // [items addObject:contacts]; 
      } 

      //ABRecordRef 
      // CFRelease(addressBook2); 
      // CFRelease(person); 
      // CFRelease(source2); 
      // CFRelease(allPeople2); 
      // NSLog([NSString stringWithFormat:@"%d",i]); 
      } 

      // se guarda en memoria numero de contactos 
      NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

      [defaults setObject:[NSString stringWithFormat:@"%d",(int)nPeople] forKey:@"numeroContactos"]; 

      [defaults synchronize]; 

     } 



    } 
    else 
    { 
     UIAlertView *alertFailSave = [[UIAlertView alloc] initWithTitle:@"Error" 
                   message:NSLocalizedString(@"TEXT_ACCESS", nil) 
                   delegate:nil 
                 cancelButtonTitle:NSLocalizedString(@"LO_BUTTON_OK", nil) 
                 otherButtonTitles:nil];   
     [alertFailSave show]; 
    } 

} 
+0

不要在这里使用信号量。相反,了解异步处理程序的工作方式。他们希望是异步的,你应该让它们是异步的。 – matt 2014-09-30 16:46:18

+0

@matt我可以做你说你给我的例子? – user1555264 2014-09-30 18:56:11

+0

究竟是什么的例子?你所说的只是“我有线程问题。”所以停止使用线程。您不知道在完成处理程序之前是否授予访问权限,所以_that_是进行下一步骤的地方。这就是完成处理程序是_for_;这意味着,这个过程是_completed_。 – matt 2014-09-30 18:58:00

回答

0

LAcorrecciónFUE cambiar EL siguiente codigo:

// ABAddressBookRef ADDRESSBOOK = ABAddressBookCreateWithOptions (NULL,错误); // ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook); // CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook,source,kABPersonSortByFirstName); // CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); // NSMutableArray * items = [NSMutableArray arrayWithCapacity:nPeople];

por este。

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error); 
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook); 
    CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);