我的代码有一个非常奇怪的错误。实际上,根本没有错误,只是调试器以“程序收到信号:“EXC_BAD_ACCESS””消息开始。
谁能帮我?我绝对感到困惑...谢谢。

-(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;
}

控制台输出为:
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)

按继续输出“EXC_BAD_ACCESS”消息。 Xcode显示,我代码中最新执行的字符串是CFRelease(addressBookRef);

最佳答案

我在做类似的事情时遇到了同样的问题,经过进一步的研究,我发现我已经发布了。根据Core Foundation docs:



我的意思是,您不应释放带有Get字样的功能。如果这样做,它将在以后的真实所有者尝试释放它时引起问题。因此,在这种情况下,当您执行以下操作时:

ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);

然后:
CFRelease(recordRef);

您正在发布不应发布的内容。很久以后,您执行以下操作:
CFRelease(allPeopleRef);

阵列将尝试释放所有记录,但不知道您已经释放了其中的一些记录。结果是您的错误。通过注释掉该行,您可能使错误消失了,但是我担心您造成了内存泄漏。

我建议您不要在Get方法指针上调用CFRelease,而应在Create或Copy方法指针上调用它(此规则可能有异常(exception),但到目前为止对我有用)。

关于iPhone SDK : EXC_BAD_ACCESS with CFRelease for ABAddressBookRef,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1209130/

10-11 12:08