2016-06-15 1 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 (책을)를 실행하면, 그건 추락했습니다. 왜? 나는 book의 변수가 nil이 아니기 때문에 이미 풀 수 있다고 결정했다. 도움을 주시면 감사하겠습니다.

답변

0

우선 ABAddressBookRequestAccessWithCompletion은 비동기 함수입니다. 즉각적으로 반환하고, 전달한 블록은 나중에 처리됩니다. 반환하는 연락처 배열은 항상 비어 있습니다.

충돌과 관련하여 CFRelease를 호출하면 블록 안에 있으면 안됩니다. 블록을 실행 한 후 ABAddressBookRequestAccessWithCompletion이 책 참조로 수행하는 작업을 알지 못합니다!

ARC 관리 속성에 대한 브리지 전송을 수행하고 주소록을 사용하는 동안 계속 유지하십시오.

+0

코드를 제공 할 수 있습니까? 나는 그것을 해결하는 방법을 모른다. –

+0

사려 깊은 배려 끝에 생각이 들었습니다. 스택 영역에서 힙 변수 (힙 변수 인 변수)로 변수의 책을 복사했는데 힙 변수를 릴리스 할 때 충돌이 발생했습니다. 내가 맞습니까? –

관련 문제