代码之家  ›  专栏  ›  技术社区  ›  beefon

iphonesdk:EXC_BAD_使用CFRelease访问ABAddressBookRef

  •  5
  • beefon  · 技术社区  · 16 年前

    我的代码有一个非常奇怪的错误。。事实上,根本并没有错误,只是调试器以“ProgramReceivedSignal: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) 
    

    按Continue可输出“EXC\u坏访问”消息。Xcode显示,代码中最新执行的字符串是 CFRelease(addressBookRef);

    2 回复  |  直到 16 年前
        1
  •  15
  •   Donald Byrd    16 年前

    我在做类似的事情时也有同样的问题,经过进一步的研究,我发现我释放过度了。根据 Core Foundation docs :

    如果您创建或复制一个核心 随后,在您需要时释放它 结束了。

    我认为这意味着带有Get一词的函数不应该由您发布。如果您这样做,它将导致一个问题,稍后当真正的所有者试图释放它。因此,在这种情况下,当您执行以下操作时:

    ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);
    

    CFRelease(recordRef);
    

    你正在释放一些不应该被释放的东西。很久以后,当您这样做时:

    CFRelease(allPeopleRef);
    

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

    CFRelease 在…上 收到 创造 复制

        2
  •  -2
  •   Sam    16 年前

    allPeopleRef和addressBookRef指向相同的对象?副本可能很浅。AbAddressBookCopyArrayFallPeople做什么?