Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C属性与内存管理_Objective C_Properties - Fatal编程技术网

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