Objective-C属性与内存管理
给定以下属性定义:Objective-C属性与内存管理,objective-c,properties,Objective C,Properties,给定以下属性定义: @property (nonatomic,retain) MyObject* foo; 以下代码是否导致内存泄漏: self.foo = [[MyObject alloc] init]; ? 看起来alloc调用将对象上的retain计数增加到1,然后属性setter中的retain将其增加到1。但由于初始计数永远不会减少到0,因此即使释放self,对象也会粘住。这种分析正确吗 如果是这样,我似乎有两个选择: self.foo = [[[MyObject alloc] i
@property (nonatomic,retain) MyObject* foo;
以下代码是否导致内存泄漏:
self.foo = [[MyObject alloc] init];
?
看起来alloc调用将对象上的retain计数增加到1,然后属性setter中的retain将其增加到1。但由于初始计数永远不会减少到0,因此即使释放self,对象也会粘住。这种分析正确吗
如果是这样,我似乎有两个选择:
self.foo = [[[MyObject alloc] init] autorelease];
出于性能原因,不建议在iPhone上使用,或者:
MyObject* x = [[MyObject alloc] init];
self.foo = x
[x release];
这有点麻烦。还有其他选择吗
还有其他选择吗
没有
如果不使用autorelease,您将无法编写大部分iPhone应用程序,Cocoa Touch库在许多地方都使用它们。理解它在做什么(将指针添加到列表中以便在下一帧中删除),并避免在紧循环中使用它
您可以在MyObject上使用类方法,该方法为您执行alloc/init/autorelease来清理它
+ (MyObject *)object {
return [[[MyObject alloc] init] autorelease];
}
self.foo = [MyObject object];
在iPhone上管理保留属性的最简单方法如下(autorelease并不像您想象的那么糟糕,至少在大多数情况下是如此):
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;
}
你说得对,
self.foo=[[MyObject alloc]init]代码>正在泄漏内存。两种选择都是正确的,可以使用。关于此类语句中的autorelease
:请记住,当前运行循环结束时,对象将由autorelease池释放,但它很可能会被self
保留更长的时间,因此,这里没有内存使用峰值问题。这是一个很好的选择,可以在创建实例时节省时间。-1因为没有调用[super init]
或[super dealoc]
,这是危险的。我的错误,我只是指出了someObject分配方法。代码已更新。这仍然是错误的,事实上的init
方法涉及将[super init]
的返回值分配给self
。
// 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;
}