2010-02-18 43 views
5

鉴于以下属性定义:Objective-C的性能和内存管理

@property (nonatomic,retain) MyObject* foo; 

没有下面的代码会导致内存泄漏:

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

看起来像alloc调用将对象上的保留计数递增到1,然后属性设置器中的保留将其增加到1.但是由于初始计数永远不会递减为0,因此即使在自我释放。分析是否正确?

如果是这样,它看起来像我有两个选择:不推荐在iPhone上由于性能原因,或

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

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

这是一个有点麻烦。还有其他的选择吗?

回答

2

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

3

有没有其他的选择?

你是不是要能写多少的iPhone应用程序,而无需使用自动释放和可可触摸库使用他们在很多地方号。了解它正在做什么(将指针添加到下一帧的清除列表中)并避免在紧密循环中使用它。

你可以在MyObject上使用class方法来为你进行alloc/init/autorelease清理工作。

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

self.foo = [MyObject object]; 
+0

这是一个很好的选择,可以在创建实例时节省时间。 – 2010-02-18 23:05:56

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; 
} 
+0

-1不会调用'[super init]'和'[super dealloc]',这很危险。 – MrMage 2010-02-18 23:11:19

+0

我的错误,我只是指出someObject的分配方法。代码已更新。 – 2010-02-18 23:13:08

+0

这仍然是错误的,事实上'init'方法涉及将'[super init]'的返回值赋给'self'。 – dreamlax 2010-02-19 00:58:47