2016-06-15 5 views
0

CFRelease (book); переменная книги является объектом ABAddressBookRef. Почему я получил это разбился? Полностью код ниже:, когда он работает здесь: CFRelease (book); что EXC_BAD_ACCESS (код = EXC_l386_GPFLT)

- (NSArray *)getAllContactsBeneathiOS9:(NSString *__autoreleasing *)err 
{ 
    __block NSMutableArray *contactArray = [[NSMutableArray alloc] init]; 

    //1.Create Address Book instance. 
    ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL); 

    //2.Request to access the Address Book 
    ABAddressBookRequestAccessWithCompletion(book, ^(bool granted, CFErrorRef error) { 
     if(granted){ 
      //Access Success 
      NSArray * allPeople = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(book); 

      for (int i = 0; i < allPeople.count; i++) { 
       ABRecordRef alPeople = (__bridge ABRecordRef)(allPeople[i]); 

       ZRContactItem *item = [[ZRContactItem alloc] init]; 

       NSString *firstName = (__bridge NSString *)ABRecordCopyValue(alPeople, kABPersonFirstNameProperty); 
       NSString *middleName = (__bridge NSString *)ABRecordCopyValue(alPeople, kABPersonMiddleNameProperty); 
       NSString *lastName = (__bridge NSString *)ABRecordCopyValue(alPeople, kABPersonLastNameProperty); 

       ABMultiValueRef phone = ABRecordCopyValue(alPeople, kABPersonPhoneProperty); 
       CFArrayRef phoneArray = ABMultiValueCopyArrayOfAllValues(phone); 
       NSMutableArray *phoneList = [[NSMutableArray alloc] init]; 
       if (phoneArray) { 
        CFIndex phoneCount = CFArrayGetCount(phoneArray); 
        for (CFIndex j = 0 ; j < phoneCount; j++) { 
         CFStringRef mobile = ABMultiValueCopyValueAtIndex(phone, j); 
         [phoneList addObject:(__bridge NSString *)mobile]; 
         CFRelease(mobile); 
        } 
       } 
       if (phoneArray) CFRelease(phoneArray); 
       if (phone) CFRelease(phone); 

       ABMultiValueRef email = ABRecordCopyValue(alPeople, kABPersonEmailProperty); 
       CFArrayRef emailArray = ABMultiValueCopyArrayOfAllValues(email); 
       NSMutableArray *emailList = [[NSMutableArray alloc] init]; 
       if (emailArray) { 
        CFIndex emailCount = CFArrayGetCount(emailArray); 
        for (CFIndex j = 0 ; j < emailCount; j++) { 
         CFStringRef mail = ABMultiValueCopyValueAtIndex(email, j); 
         [emailList addObject:(__bridge NSString *)mail]; 
         CFRelease(mail); 
        } 
       } 
       if (emailArray) CFRelease(emailArray); 
       if (email) CFRelease(email); 

       ABMultiValueRef address = ABRecordCopyValue(alPeople, kABPersonAddressProperty); 
       CFArrayRef addrArray = ABMultiValueCopyArrayOfAllValues(address); 
       NSMutableArray *addrList = [[NSMutableArray alloc] init]; 
       if (addrArray) { 
        CFDictionaryRef dic = CFArrayGetValueAtIndex(addrArray, 0); 
        NSString *city = (__bridge NSString *)CFDictionaryGetValue(dic, kABPersonAddressCityKey); 
        NSString *CountryCode = (__bridge NSString *)CFDictionaryGetValue(dic, kABPersonAddressCountryCodeKey); 
        NSString *Country = (__bridge NSString *)CFDictionaryGetValue(dic, kABPersonAddressCountryKey); 
        NSString *State = (__bridge NSString *)CFDictionaryGetValue(dic, kABPersonAddressStateKey); 
        NSString *Street = (__bridge NSString *)CFDictionaryGetValue(dic, kABPersonAddressStreetKey); 
        NSString *ZIP = (__bridge NSString *)CFDictionaryGetValue(dic, kABPersonAddressZIPKey); 

        NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] init]; 
        dic1[@"street"] = Street; 
        dic1[@"city"] = city; 
        dic1[@"state"] = State; 
        dic1[@"postalCode"] = ZIP; 
        dic1[@"country"] = Country; 
        dic1[@"countryCode"] = CountryCode; 
        [addrList addObject:dic1]; 

        CFRelease(dic); 
       } 
       if (addrArray) CFRelease(addrArray); 
       if (address) CFRelease(address); 

       item.givenName = [self isnil:firstName]; 
       item.familyName = [self isnil:lastName]; 
       item.middleName = [self isnil:middleName]; 
       item.phoneNumbers = phoneList; 
       item.email = emailList; 
       item.address = addrList; 
       [contactArray addObject:item]; 

       if (alPeople) CFRelease(alPeople); 
      } 
     }else{ 
      //Access denied. 
      *err = @"Grant this application to access your Contacts, please! "; 
      NSLog(@"%@", *err); 
     } 
     //Release book instance 
     if (book) CFRelease(book); 
    }); 
    return contactArray; 
} 

Когда он работает CFRelease (книга); который разбился. Зачем? Я уже определил, что переменная книги не нуль, так что она может освободиться. Любая помощь приветствуется!

ответ

0

Прежде всего, ABAddressBookRequestAccessWithCompletion является асинхронной функцией. Он немедленно возвращается, и блок, который вы передаете ему, выполняется в какой-то более поздний момент. Возвращаемый массив контактов всегда будет пустым.

Что касается аварии, если вы вообще вызываете CFRelease, он не должен находиться внутри блока. Вы не знаете, что делает ABAddressBookRequestAccessWithCompletion с ссылкой на книгу после запуска блока!

Попробуйте выполнить перенос моста в управляемое свойство ARC и просто держитесь за него, когда работаете с адресной книгой.

+0

Можете ли вы дать мне код? Я не знаю, как его решить. –

+0

После задумчивого рассмотрения у меня появилась идея. Я скопировал книгу переменной из области стека в область кучи, переменную, которая является переменной кучи, она разбилась при выпуске переменной кучи. Я прав? –

Смежные вопросы