我正在努力了解一些内存管理问题。并找到this question,它部分回答了我的问题。
例如,在MyObject中,我有一个声明为属性的实例变量,并在实现文件中正确合成:
@interface MyObject : NSObject
...
ObjectA objA;
...
@property (nonatomic, retain) ObjectA *objA;
@end
在任意点,我实例化objA。我知道self.objA = _objA;
调用了合成访问器。从逻辑上讲,这意味着self.objA = [[ObjectA alloc] init];
会导致内存泄漏,因为保留计数会比预期多一个(我知道直接检查保留计数并不是检查对象多长时间的准确方法)在记忆中。)
objA = [[ObjectA alloc] init;
是否也会调用setter,并可能导致内存泄漏?
答案 0 :(得分:4)
在没有“self”的情况下调用属性名称。跳过setter并直接更新实例变量。
为了避免混淆和潜在的内存泄漏,我喜欢重命名合成属性的实例变量,如下所示:
@synthesize objA = _objA;
你的课程看起来像这样:
@interface MyObject : NSObject
...
@property (nonatomic, retain) ObjectA *objA;
@end
现在,如果你忘记了“自我”,你将会遇到一个编译器错误,而且你会更明确地知道你实际使用的是哪个变量。
答案 1 :(得分:3)
将alloc
/ init
的结果分配给原始实例变量是完全可以接受的,建议在初始化方法中设置实例变量。为避免在使用合成设置器时泄漏内存,您可以采用两种方法。
<强> 1。自动释放强>
self.objA = [[ObjectA alloc] init] autorelease];
通过'retain'属性的setter会增加保留计数。 alloc / init也增加了保留计数,但是通过自动释放来平衡,这意味着它将减1并且当前事件循环结束。
<强> 2。首先分配给临时变量
// +alloc/-init increments the retain count of objectA to 1
ObjectA objectA = [[ObjectA alloc] init];
// Synthesized setter calls retain on objectA, incrementing to 2.
self.objA = objectA;
// Decrement objectA's retain count to 1.
[objectA release];
答案 2 :(得分:2)
objA = [[ObjectA alloc] init];
不使用setter方法,而是直接设置实例变量。所以保留计数从alloc
开始为1。