2011-12-19 40 views
1

我有几个UIView子类(按钮,标签等)遵循以下安装模式。我的问题是,为什么邮件仍然可以在release之后发送到UILabel将消息发送到发布的对象?

myLabel = [[UILabel alloc] initWithFrame:someFrame]; 
    [someUIView addSubview:myLabel]; 
    [myLabel release]; 

    myLabel.textAlignment = UITextAlignmentCenter; 

    // other property changes to myLabel 

他们被新的UIView“拥有”,我想,但我不明白为什么release不破坏原来的对象,因而所有的消息吧。我不通过someUIViewsubViews进行财产更改。我没有抱怨。我只是想明白为什么。

编辑:我应该补充说,这些是实例变量,如果这有所作为。

回答

1

,您仍然可以将消息发送到标签,因为标签还没有被释放。 -addSubview:保留传入的对象,因此该对象保留在内存中,因为该视图仍然保存引用,并且您没有指定myLabel指针。

+0

完美!谢谢!我如何知道另一种方法何时会隐式调用发布?有一些我应该知道的清单吗? (除了查看NSObject的retainCount) – 2011-12-19 00:49:35

+1

释放一个对象后不要使用它。 – zaph 2011-12-19 00:52:51

+2

简短的回答是......不用担心。当然,我碰巧知道'-addSubview:'在对象上执行保留,但这不是必需的。至于'retainCount',就不要打扰。认真。这是一个只会导致疯狂的实现细节。 – 2011-12-19 00:53:53

0

因为他们可能之前保留...

+0

这就是我想,但经过进一步检查,我看不出有什么明显的先保留。 – 2011-12-19 00:39:48

1

当您收到它时,您致电-addSubview:时会在标签上标注-retain。此时,您放弃所有权(通过呼叫-release),只有视图拥有它。但它仍然存在,直到包含视图也释放它。

3

只要保留计数大于0,对象就不会被破坏。在这种情况下,someUIView保留了该对象。

最好不要在释放对象后访问对象。一个更好的模式可能是:

myLabel = [[[UILabel alloc] initWithFrame:someFrame] autorelease]; 
myLabel.textAlignment = UITextAlignmentCenter; 
[someUIView addSubview:myLabel]; 
myLabel = nil; 

第二个例子:

myLabel = [[UILabel alloc] initWithFrame:someFrame]; 
[someUIView addSubview:myLabel]; 
myLabel.textAlignment = UITextAlignmentCenter; 

// other property changes to myLabel 

[myLabel release]; 
myLabel = nil; 
+0

我在发布之后发生属性更改的唯一原因是因为该类中的其他方法正在更改它们。如果在任何特定时间,我不确定还有什么地方可以发布,另一种方法可能会改变它的属性。 – 2011-12-19 00:52:55

+0

然后在设置'textAlignment'后释放,参见我的第二个例子。一个建议“使用ARC,它会处理所有的保留和释放。 – zaph 2011-12-19 01:10:21

+0

如果'myLabel'是一个实例变量,并且你的类中的其他方法可能会改变'myLabel',那么每一个更改应该先释放现有的值,然后重新分配。但是,这听起来非常脆弱,如果那真的是这样的话;你如何确保这个'textAlignment'保持一致? – bbum 2011-12-19 03:49:49