Objective-C属性和内存管理

时间:2010-02-18 22:57:45

标签: objective-c properties

给出以下属性定义:

@property (nonatomic,retain) MyObject* foo;

以下代码会导致内存泄漏:

self.foo = [[MyObject alloc] init];

看起来alloc调用会将对象的保留计数增加到1,然后属性setter中的retain会将其增加到1.但由于初始计数从未递减为0,所以即使在self时对象也会保持不变被释放。这种分析是否正确?

如果是这样,看起来我有两种选择:

self.foo = [[[MyObject alloc] init] autorelease];

出于性能原因不建议在iPhone上使用,或者:

MyObject* x = [[MyObject alloc] init];
self.foo = x
[x release];

这有点麻烦。还有其他选择吗?

3 个答案:

答案 0 :(得分:3)

  

还有其他选择吗?

没有

如果不使用自动释放,你将无法编写大量的iPhone应用程序,Cocoa Touch库会在很多地方使用它们。理解它正在做什么(将指针添加到下一帧的删除列表中)并避免在紧密循环中使用它。

你可以在MyObject上使用class方法来执行alloc / init / autorelease来清理它。

+ (MyObject *)object {
    return [[[MyObject alloc] init] autorelease];
}

self.foo = [MyObject object];

答案 1 :(得分:3)

在iPhone上管理保留属性的最简单方法如下(自动释放并不像您想象的那么糟糕,至少对于大多数用途而言):

-(id)init {
    if (self = [super init]) {
        self.someObject = [[[Object alloc] init] autorelease];
    }
    return self;
}

-(void)dealloc {
    [someObject release];
    [super dealloc];
}

autorelease释放对分配给self.object的浮动实例的引用,该实例保留了自己的引用,为您提供了所需的引用(someObject)。然后,当类被销毁时,唯一剩下的引用被释放,从而破坏对象。

如另一个答案所述,您还可以创建一个或多个“构造函数”消息,以使用可选参数创建和自动释放对象。

+(Object)object;
+(Object)objectWithCount:(int)count;
+(Object)objectFromFile:(NSString *)path;

可以将这些定义为:

// No need to release o if fails because its already autoreleased
+(Object)objectFromFile:(NSString *)path {
    Object *o = [[[Object alloc] init] autorelease];
    if (![o loadFromFile:path]) {
        return nil;
    }
    return o;
}

答案 2 :(得分:2)

你是对的,self.foo = [[MyObject alloc] init];正在泄漏记忆。两种选择都是正确的,可以使用。关于这样一个语句中的autorelease:请记住,一旦当前运行循环结束,对象将由自动释放池释放,但它很可能会被self保留更长时间,所以这里的内存使用率没有问题。