如何正确使用 CFRetain 和 CFRelease?

How do I use CFRetain and CFRelease properly?

下面是一些示例代码:

@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. 您不能将属性 setter/getter方法与手动内存管理功能一起使用,例如malloc、free、CFRetain、CFRelease、CFCopy、CFCreate等。您必须使用实例变量直接(即使用 m_foo 而不是 self.foo

  2. 如果 foo 是 read/write 属性 那么您必须提供一个自定义 setter 实现来正确处理内存管理。

例如,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 不需要是 public 属性 那么您可能只想摆脱它并专门使用实例变量。