我是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。从标准化的角度来看,这是正确的吗?它看起来与我有点不同,但我又是新手。
由于
答案 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];