如何正确使用 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 警告我 CFAttributedStringCreateCopy
和 CFRelease
可能存在内存泄漏。为什么?
编辑: 如果我直接使用成员变量 m_foo
,它会更正问题。 属性 的内存管理语义是否有误?
您不能将属性 setter/getter方法与手动内存管理功能一起使用,例如malloc、free、CFRetain、CFRelease、CFCopy、CFCreate等。您必须使用实例变量直接(即使用 m_foo
而不是 self.foo
)
如果 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 属性 那么您可能只想摆脱它并专门使用实例变量。
下面是一些示例代码:
@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 警告我 CFAttributedStringCreateCopy
和 CFRelease
可能存在内存泄漏。为什么?
编辑: 如果我直接使用成员变量 m_foo
,它会更正问题。 属性 的内存管理语义是否有误?
您不能将属性 setter/getter方法与手动内存管理功能一起使用,例如malloc、free、CFRetain、CFRelease、CFCopy、CFCreate等。您必须使用实例变量直接(即使用
m_foo
而不是self.foo
)如果
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 属性 那么您可能只想摆脱它并专门使用实例变量。