2009-07-30 28 views
5

có lỗi rất lạ với mã của tôi .. Trên thực tế, không có lỗi nào cả, chỉ trình gỡ lỗi bắt đầu bằng thông báo "Đã nhận tín hiệu chương trình:" EXC_BAD_ACCESS "". Có ai giúp tôi không? Tôi hoàn toàn bối rối ... Cảm ơn bạn.SDK iPhone: EXC_BAD_ACCESS với CFRelease cho ABAddressBookRef

-(NSString *)fullNameForPhone:(NSString *)ph withAlternativeText:(NSString *)text 
{ 
    ABAddressBookRef addressBookRef = ABAddressBookCreate(); 
    NSLog(@"create addressBookRef"); 
    NSString *stringToReturn = text; 

    CFArrayRef allPeopleRef = ABAddressBookCopyArrayOfAllPeople(addressBookRef); 
    NSLog(@"create allPeopleRef"); 
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBookRef); 

    int i = 0; 
    BOOL nameFound = NO; 

    while ((i < nPeople) && (!nameFound)) 
    { 
     ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i); 
     NSLog(@" create recordRef"); 
     CFStringRef allRecordPhonesRef = ABRecordCopyValue(recordRef, kABPersonPhoneProperty); 
     NSLog(@" create allRecordPhonesRef"); 
     CFIndex nPhones = ABMultiValueGetCount(allRecordPhonesRef); 
     int currentPhone = 0; 
     for (currentPhone = 0; currentPhone < nPhones; currentPhone++) 
     { 
      CFStringRef currentPhoneNumberRef = ABMultiValueCopyValueAtIndex(allRecordPhonesRef, currentPhone); 
      NSLog(@"   create currentPhoneNumberRef"); 
      NSString *currentCleanPhoneNumber = [self cleanPhoneNumberForString:[NSString stringWithFormat:@"%@", currentPhoneNumberRef]]; 
      if (currentPhoneNumberRef!=NULL) 
      { 
       NSLog(@"   release currentPhoneNumberRef"); 
       CFRelease(currentPhoneNumberRef); 
      } 

      if ([ph isEqualToString:currentCleanPhoneNumber]) 
      { 
       CFStringRef firstName = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty); 
       CFStringRef lastName = ABRecordCopyValue(recordRef, kABPersonLastNameProperty); 
       NSString *fullName = [self fullNameForFirstName:[NSString stringWithFormat:@"%@", firstName] 
                andLastName:[NSString stringWithFormat:@"%@", lastName]]; 
       if (firstName != NULL) 
        CFRelease(firstName); 
       if (lastName != NULL) 
        CFRelease(lastName); 
       stringToReturn = fullName; 
       nameFound = YES; 
       break; 
      } 

     } 

     CFRelease(allRecordPhonesRef); 
     NSLog(@" release allRecordPhonesRef"); 
     CFRelease(recordRef); 
     NSLog(@" release recordRef"); 
     i++; 
    } 
    CFRelease(allPeopleRef); 
    NSLog(@"release allPeopleRef"); 
    CFRelease(addressBookRef); 
    NSLog(@"release addressBookRef"); 
    return stringToReturn; 
} 

điều khiển đầu ra là:

2009-07-31 00:20:05.230 abmodular[21747:20b] create addressBookRef 
2009-07-31 00:20:05.231 abmodular[21747:20b] create allPeopleRef 
2009-07-31 00:20:05.231 abmodular[21747:20b] create recordRef 
2009-07-31 00:20:05.232 abmodular[21747:20b] create allRecordPhonesRef 
2009-07-31 00:20:05.232 abmodular[21747:20b]   create currentPhoneNumberRef 
2009-07-31 00:20:05.232 abmodular[21747:20b]   release currentPhoneNumberRef 
2009-07-31 00:20:05.232 abmodular[21747:20b]   create currentPhoneNumberRef 
2009-07-31 00:20:05.233 abmodular[21747:20b]   release currentPhoneNumberRef 
2009-07-31 00:20:05.233 abmodular[21747:20b] release allRecordPhonesRef 
2009-07-31 00:20:05.233 abmodular[21747:20b] release recordRef 
2009-07-31 00:20:05.233 abmodular[21747:20b] create recordRef 
2009-07-31 00:20:05.234 abmodular[21747:20b] create allRecordPhonesRef 
2009-07-31 00:20:05.234 abmodular[21747:20b]   create currentPhoneNumberRef 
2009-07-31 00:20:05.234 abmodular[21747:20b]   release currentPhoneNumberRef 
2009-07-31 00:20:05.234 abmodular[21747:20b] release allRecordPhonesRef 
2009-07-31 00:20:05.235 abmodular[21747:20b] release recordRef 
2009-07-31 00:20:05.235 abmodular[21747:20b] release allPeopleRef 
[Session started at 2009-07-31 00:20:05 +0400.] 
GNU gdb 6.3.50-20050815 (Apple version gdb-966) 
.... 
Attaching to process 21747. 
kill 
quit 
The Debugger has exited with status 0.(gdb) 

Nhấn Continue đầu ra "EXC_BAD_ACCESS" tin nhắn. Xcode cho thấy, chuỗi được thực thi mới nhất trong mã của tôi là CFRelease(addressBookRef);

Trả lời

15

Tôi đã gặp vấn đề tương tự khi làm điều tương tự và khi nghiên cứu sâu hơn, tôi phát hiện ra rằng tôi đã phát hành hơn. Theo Core Foundation docs:

Nếu bạn tạo hoặc sao chép một Core đối tượng Foundation, bạn phải sau đó phát hành nó khi bạn đang xong với nó.

Tôi đọc điều đó có nghĩa là chức năng với từ Nhận sẽ không được bạn phát hành. Nếu bạn làm vậy, nó sẽ gây ra vấn đề sau này khi chủ sở hữu thực sự cố gắng giải phóng nó. Vì vậy, trong trường hợp này khi bạn làm:

ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i); 

và sau:

CFRelease(recordRef); 

bạn đang giải phóng cái gì đó không có nghĩa vụ phải được phát hành. Phần lớn sau đó khi bạn làm:

CFRelease(allPeopleRef); 

mảng sẽ cố gắng giải phóng tất cả hồ sơ của nó mà không biết bạn đã phát hành một số bản ghi. Kết quả là lỗi của bạn. Bằng cách bình luận ra rằng dòng bạn có thể đã làm cho các lỗi biến mất nhưng tôi lo sợ bạn đã tạo ra một rò rỉ bộ nhớ.

tôi đề nghị bạn đừng gọi CFRelease trên Nhận phương pháp gợi ý và làm gọi nó trên Tạo hoặc Sao chép phương pháp gợi ý (có thể có ngoại lệ cho quy tắc này nhưng cho đến nay nó làm việc cho tôi).

+0

Cảm ơn bạn rất nhiều. Bây giờ không có rò rỉ. – beefon

+0

rực rỡ, cảm ơn bạn – Eugene

+0

cảm ơn người đàn ông. tuyệt quá –

-2

allPeopleRef và addressBookĐiểm đến cùng một đối tượng? Bản sao có lẽ là nông cạn. ABAddressBookCopyArrayOfAllPeople làm gì?

+0

ABAddressBookCopyArrayOfAllPeople Trả về tất cả bản ghi của người trong sổ địa chỉ. CFArrayRef ABAddressBookCopyArrayOfAllPeople ( ABAddressBookĐịa chỉ emailĐịa chỉ ); Tham số addressBook Sổ địa chỉ có người ghi lại. Giá trị trả lại Mảng có chứa bản ghi người trong sổ địa chỉ. Tính khả dụng Có trong iPhone OS 2.0 trở lên. Đã khai báo trong ABPerson.h – beefon

+0

Điều gì xảy ra nếu bạn nhận xét CFRelease (allPeopleRef); ? – Sam

+0

Cảm ơn bạn đã trả lời! Sau khi bình luận ra CFRelease (allPeopleRef); nó hoạt động chính xác ngay bây giờ! Cảm ơn bạn.Tại sao addressBookRef và allPeopleRef trỏ đến cùng một đối tượng? Tôi nghĩ rằng ABAddressBookCopyArrayOfAllPeople chức năng sẽ trở lại ít nhất là bản sao của tất cả hồ sơ .. – beefon

Các vấn đề liên quan