如何正确使用CFRetain和CFRelease?

时间:2015-06-30 04:44:17

标签: objective-c memory-management

以下是一些示例代码:

@interface Foo : NSObject
{
    CFAttributedStringRef m_foo;
}
@property (nonatomic, assign) CFAttributedStringRef foo;
@end

@implementation Foo
@synthesize foo = m_foo;

- (id)initWithAttributedString:(CFAttributedStringRef)attributedString
{
    self = [super init];
    if (self == nil)
        return nil;

    if (attributedString != NULL)
    {
        self.foo = CFAttributedStringCreateCopy(NULL, attributedString);
    }

    return self;
}

- (void)dealloc
{
    if (self.foo != NULL)
        CFRelease(self.foo);

    [super dealloc];
}

@end

XCode警告我CFAttributedStringCreateCopyCFRelease的潜在内存泄漏。为什么呢?

编辑:如果我直接使用成员变量m_foo,则会更正问题。我的属性的内存管理语义是否错误?

1 个答案:

答案 0 :(得分:2)

  1. 您不能将属性设置器/ getter方法与手动内存管理功能(如malloc,free,CFRetain,CFRelease,CFCopy,CFCreate等)一起使用。您必须直接使用实例变量(即使用m_foo而不是self.foo

  2. 如果foo是读/写属性,那么您必须提供正确处理内存管理的自定义setter实现。

  3. 例如,复制的setter:

    - (void)setFoo:(CFAttributedStringRef)newValue {
    
        CFAttributedStringRef oldValue = m_foo;
        if (newValue) {
            m_foo = CFAttributedStringCreateCopy(NULL, newValue);
        } else {
            m_foo = NULL;
        }
    
        if (oldValue) {
            CFRelease(oldValue);
        }
    }
    

    如果foo不需要是公共属性,那么您可能只想摆脱它并专门使用实例变量。