iphone @property(保留),init()和标准

时间:2010-06-09 12:31:37

标签: iphone properties standards

我是iphone内存管理的新手,对标准/正确性有疑问。

我的头文件声明:

 IBOutlet UITabBarController *tabBarController;
 @property (nonatomic, retain) UITabBarController *tabBarController;

在我的init()代码中,我正在执行以下操作:

self.tabBarController = [[UITabBarController alloc] init];
[tabBarController release];
NSLog(@"Retain count of tbc: %d",[tabBarController retainCount]);

将保留计数恢复为1。从标准化的角度来看,这是正确的吗?它看起来与我有点不同,但我又是新手。

由于

4 个答案:

答案 0 :(得分:3)

这是正常的。

你做了什么:

self.tabBarController = [[UITabBarController alloc] init];
[tabBarController release];

可能由编译器执行:

id *tempVar = [[UITabBarController alloc] init];
self.tabBarController = tempVar;                  //till now, retainCount is 2
[tabBarController release];                       //now, retainCount is 1

当你分配它时,这个内存块将由临时var保留。所以更好的方法是:

UITabBarController *tabCtl = [[UITabBarController alloc] init];
self.tabBarController = tabCtl;
[tabCtl release];

我不是object-c的专家,只是对编译有一些了解。所以,如果我错了,请专家指出。

答案 1 :(得分:2)

要分配属性,您应该使用

self.tabBarController = [[[UITabBarController alloc] init] autorelease];

[tabBarController release];
tabBarController = [[UITabBarController alloc] init];

(请记住先释放先前的值)

属性setter / getters应该全权负责保留/释放实例变量。如果您(或其他人)更改属性设置器以获取输入的副本而不是保留它,会发生什么?在这种情况下,您将过度释放实例变量并泄漏原始对象。

您实际上是在发送具有私有副作用的消息,然后通过在下一行释放实例变量来使用这些私有细节的知识。即你的代码与:

相同
[self setTabBarControler:[[UITabBarController alloc] init]];
/* Relying on knowledge of the instance variable is bad here, setTabBarController
   might do something different in the future */
[tabBarController release];

即使你完全掌控了这个类,你仍然应该遵循抽象和封装的基本原则。保留/释放实例变量到基础属性实现。

答案 2 :(得分:1)

为什么不

tabBarController = [[UITabBarController alloc] init];

答案 3 :(得分:1)

你可以这样做,但更好的是不要在你的init()方法中使用这种隐式setter语法(因为你可能会覆盖setter并做更多的东西,如果对象不完整的话可能还不行初始化)。

只是做:

tabBarController = [[UITabBarController alloc] init];