使用CFRelease进行ABRecordCopyValue时内存仍在增加?

时间:2010-01-20 04:39:13

标签: iphone objective-c memory-management memory-leaks

我有一个问题让人头痛,我只是创建方法:

-(void) main{

      for (int i = 0; i< 100;i++) {
           [self getPhoneOfContact:i];
      }
 }

-(void)getPhoneOfContact:(NSInteger)id_contact {

     ABRecordRef record = ABAddressBookGetPersonWithRecordID(addressBook,id_contact);

     CFTypeRef ref1;
     ref1 = ABRecordCopyValue(record,kABPersonPhoneProperty);

     CFRelease(record);
     CFRelease(ref1); 
}

我认为内存将近似常数,因为我已经复制了释放内存,但实际上它仍然会增加每个循环i; 谁能解释我这个:(。谢谢!

4 个答案:

答案 0 :(得分:5)

你的代码错了。 ABAddressBookGetPersonWithRecordID调用遵循Core Foundation的“获取规则”。这意味着您没有返回值的所有权,因此您不必释放它。

请参阅Core Foundation - Memory Management

答案 1 :(得分:0)

运行ABAddressBookGetPersonWithRecordID和/或ABRecordCopyValue可能会使用一些您不知道的自动释放对象,这会导致内存增加。但是,当最近的自动释放池耗尽时,它将被释放。这不是您的应用程序的问题。

尝试将循环放在自己的自动释放池中,并在执行循环后排空池:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// do computation
[pool release];

这会将内存“重置”为初始数量吗?

此外,一般情况下,尝试使用XCode的仪器内存泄漏而不是查看内存使用情况 - 这可能只是有用,但内存泄漏是主要工具发现,好......内存泄漏:)

答案 2 :(得分:0)

我不确定,但我认为这可能是正在发生的事情......

 // 1. alloc and return a record address to record
 ABRecordRef record = ABAddressBookGetPersonWithRecordID(addressBook,id_contact);
 // 2. alloc and return the default CFTypeRef to ref1
 CFTypeRef ref1;
 // 3. copy and return the value of kABPersonPhoneProperty
 ref1 = ABRecordCopyValue(record,kABPersonPhoneProperty);
 // release 1
 CFRelease(record);
 // release 3
 CFRelease(ref1);

因此,2仍然在泄漏。也许尝试做CFTypeRef ref1 = nil或者只是在一行上做这一切?

答案 3 :(得分:0)

这对你有用吗?实际检索信息?这是我用来从记录中检索kABPersonPhoneProperty的。

ABMutableMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty);
    for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {
        CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex(multi, i);
        CFStringRef phoneNumber      = ABMultiValueCopyValueAtIndex(multi, i);
                  // Do stuff with the info.
        CFRelease(phoneNumberLabel);
        CFRelease(phoneNumber);
    }
    CFRelease(multi);