2016-06-15 4 views
0

CFrelease (Buch); Die Variable Buch ist ein Objekt von ABAddressBookRef. Warum habe ich das abgestürzt? Der ganz Code unten:wenn es hier läuft: CFRelease (Buch); dass EXC_BAD_ACCESS (code = 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; 
} 

Wenn es CFRelease (Buch) ausgeführt wird; das ist abgestürzt. Warum? Ich habe bereits festgestellt, dass die Variable Buch ist nicht Null, so dass es freigeben kann. Jede Hilfe wird geschätzt!

Antwort

0

Zunächst ist ABAddressBookRequestAccessWithCompletion eine asynchrone Funktion. Es kehrt sofort zurück und der Block, den Sie ihm übergeben haben, wird zu einem späteren Zeitpunkt ausgeführt. Das von Ihnen zurückgegebene Kontaktfeld ist immer leer.

Wie für den Absturz, wenn Sie CFRelease überhaupt aufrufen, sollte es nicht innerhalb des Blocks sein. Sie wissen nicht, was ABAddressBookRequestAccessWithCompletion mit der Buchreferenz nach dem Ausführen des Blocks macht!

Versuchen Sie, eine Bridge-Übertragung zu einer verwalteten ARC-Eigenschaft durchzuführen, und halten Sie sie während der Arbeit mit dem Adressbuch gedrückt.

+0

Können Sie mir den Code geben? Ich weiß nicht, wie ich es lösen soll. –

+0

Nach reiflicher Überlegung bekam ich eine Idee. Ich kopierte Buch der Variablen aus dem Stapelbereich in Heap-Bereich, die Variable, die eine Heap-Variable ist, es stürzte ab, wenn ich eine Heap-Variable freigeben. Habe ich recht? –

Verwandte Themen