2011-12-16 95 views
2

我想要真正理解一些内存管理问题。并发现this question,这部分回答了我的问题。Objective-C:@property和@synthesize和内存泄漏

例如,在为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

可能重复http://stackoverflow.com/questions/7219951/preventing泄漏时使用属性和合成) – Caleb 2011-12-16 20:35:08

回答

3

alloc/init的结果分配给原始实例变量是完全可以接受的,并且建议用于在初始化方法中设置实例变量。为避免在使用合成设置器时泄漏内存,您可以采取两种方法。

1.自动释放

self.objA = [[ObjectA alloc] init] autorelease]; 

通过制定者走出 '保留' 属性递增保留计数。 alloc/init也增加了保留计数,但是被autorelease平衡,这意味着它将减1和当前事件循环的结束。


2.分配到([使用@property和@synthesize时防止泄漏]的临时变量第一

// +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]; 
4

调用没有“自我”的属性名称。跳过setter并直接更新实例变量。

为了避免混乱和潜在的内存泄漏,我喜欢合成的属性的这样的实例变量命名:

@synthesize objA = _objA; 

你的类是这样的:

@interface MyObject : NSObject 
    ... 
    @property (nonatomic, retain) ObjectA *objA; 
@end 

现在,如果你忘记了“自我”,你会得到一个编译器错误,它会更明确地表明你实际使用了哪个变量。

2

objA = [[ObjectA alloc] init];不使用setter方法,而是直接设置实例变量。所以保留计数为1,从alloc