(iphone)基本的内存管理问题

时间:2011-02-04 06:00:31

标签: iphone memory-management view

我使用了以下两种模式来创建视图。

@property (retain, nonatomic) SomeView* someView;

...

// First pattern
self.someView = [[SomeView alloc] initWithFrame frame];

// Second pattern
SomeView* aSomeView = [[SomeView alloc] initWithFrame];
self.someView = aSomeView;
[aSomeView release];

现在,回头看这段代码,第一个模式的方法应该改为

self.someView = [[[SomeView alloc] initWithFrame frame] autorelease];

不应该吗?

我感到愚蠢:(

4 个答案:

答案 0 :(得分:1)

这样看:

[[SomeView alloc] initWithFrame: frame];

上面一行创建一个对象,并为其保留计数为1。

self.someView = [[SomeView alloc] initWithFrame: frame];

这一行保留计数为2,因为someView属性是使用retain:

声明的
@property (**retain**, nonatomic) SomeView* someView;

因此,这样做会使someView属性指向一个保留计数为2的对象。如果你向它添加一个autorelease调用,你可以这样做:

self.someView = [[[SomeView alloc] initWithFrame: frame] autorelease];

如果你问我,你的第二种模式会更好。您创建一个保留计数为1的对象。你将它分配给一个保留属性(现在它的保留计数为2),然后释放原始变量,再次保留对象,保留计数为1.它是三条线,你可能只想要一条,但这是有道理的在正确的背景下。此外,通常最好避免在alloc或copy方法之外使用自动释放,因为它通常表明您不完全理解Obj-C中的内存管理。

正如评论者在评论中所说,不要觉得愚蠢。这一切都不是直观的。没人拿起吉他,第一次像亨德里克斯一样玩。

答案 1 :(得分:0)

是的,你是对的。 autorelease表示“稍后释放”。

答案 2 :(得分:0)

是的,我认为你应该改变这一点。使用self.someView =,您将调用setter来增加保留计数。

答案 3 :(得分:0)

  

现在,回头看这段代码,1的方法应该改为self.someView = [[[SomeView alloc] initWithFrame frame] autorelease];   不应该吗?

正确

A)

SomeView * view = [[SomeView alloc] initWithFrame:frame];
self.someView = view;
[view release], view = nil;

b)中

self.someView = [[[SomeView alloc] initWithFrame:frame] autorelease];

很多人更喜欢b,只因为输入的次数较少。

我更喜欢类似a的方法:

  • 缺陷(例如过度释放)经常暴露在呼叫站点附近,而不是在池被破坏时(这通常意味着您必须在Zombie模式下加载仪器以找到呼叫站点)
  • 它表现更好并且最小化内存使用量(一般情况下,但在这种特定情况下并不多)
  • 您有更多机会检查无效状态和结果
  • 您有机会在将视图/对象添加到self之前初始化/配置视图/对象,这通常是首选