我在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];
}
}
不要在這裏使用信號量。相反,瞭解異步處理程序的工作方式。他們希望是異步的,你應該讓它們是異步的。 – matt 2014-09-30 16:46:18
@matt我可以做你說你給我的例子? – user1555264 2014-09-30 18:56:11
究竟是什麼的例子?你所說的只是「我有線程問題。」所以停止使用線程。您不知道在完成處理程序之前是否授予訪問權限,所以_that_是進行下一步驟的地方。這就是完成處理程序是_for_;這意味着,這個過程是_completed_。 – matt 2014-09-30 18:58:00