iPhone SDK:EXC_BAD_ACCESS与CFRelease for ABAddressBookRef [英] iPhone SDK: EXC_BAD_ACCESS with CFRelease for ABAddressBookRef

查看:130
本文介绍了iPhone SDK:EXC_BAD_ACCESS与CFRelease for ABAddressBookRef的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码出现了非常奇怪的错误。事实上,根本没有错误,只是调试器以程序接收信号:EXC_BAD_ACCESS消息开始。
任何人都可以帮助我吗?我非常困惑...谢谢。

there's very strange error with my code.. In fact, there's no errors at all, just debugger starts with "Program received signal: "EXC_BAD_ACCESS"" message. Can anyone help me? I'm absolutely confused... Thank you.

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

Pressing Continue outputs "EXC_BAD_ACCESS" message. Xcode shows, that the latest executed string in my code was CFRelease(addressBookRef);

推荐答案

我做同样的事情做了类似的事情,经过进一步的研究,我发现我已经过度释放了。根据 Core Foundation docs

I had the same issue doing something similiar and upon further research I discovered I was over releasing. According to the Core Foundation docs:


如果您创建或复制Core
基金会对象,您必须在
完成后随后发布
有了它。

If you create or copy a Core Foundation object, you must subsequently release it when you’re finished with it.

我认为这意味着不应该释放带有Get字样的功能。如果这样做,稍后当真正的所有者试图释放它时将导致问题。所以,在这种情况下你这样做:

I read that as meaning that functions with the word Get should not be released by you. If you do, it will cause an issue later on when the real owner attempts to release it. So, in this case when you do:

ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);

及以后:

CFRelease(recordRef);

您正在发布不应发布的内容。很久以后你这样做:

you are releasing something that is not supposed to be released. Much later when you do:

CFRelease(allPeopleRef);

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

the array will attempt to release all its records not knowing you have already released some of them. The result is your error. By commenting out that line you may have made the error go away but I fear you have created a memory leak.

我建议你不要打电话给 获取方法指针上的CFRelease 并在创建复制方法指针上调用它(可能有例外)规则,但到目前为止它适用于我)。

I suggest you do not call CFRelease on Get method pointers and do call it on Create or Copy method pointers (there may be exceptions to this rule but so far it works for me).

这篇关于iPhone SDK:EXC_BAD_ACCESS与CFRelease for ABAddressBookRef的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆