iphone @property(retain)、init() 和标准

发布于 2024-09-05 02:59:56 字数 481 浏览 2 评论 0原文

我是 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。从标准化的角度来看,这是否正确?它对我来说看起来有点不同,但我又对此感到陌生。

谢谢

I'm new to the memory management of the iphone and had a question about standards/correctness.

My header file declares:

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

In my init() code I was doing something like the following:

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

to get the retain count back to one. Is this correct from a standardization point of view? It just looked a bit different to me, but again I'm new to this.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无人问我粥可暖 2024-09-12 02:59:56

这很正常。

你做什么:

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

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

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

我不是object-c的专家,只是有一些关于编译的知识。所以,如果我说得不对,还请各位专家指出。

That's normal.

What you do:

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

maybe performed by compiler as:

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

When you alloc it, this memory block will be retained by a temporary var. So a better way to do that is:

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

I'm not an expert of object-c, just have some knowledge about compiling. So, if I'm wrong, experts here please point out.

甜柠檬 2024-09-12 02:59:56

要分配给属性,您应该使用

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

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

(记住首先释放以前的值)

属性 setters/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];

即使您完全控制该类,您仍然应该遵守抽象和封装的基本原则。将实例变量的保留/释放留给底层属性实现。

For assigning to the property, you should either use

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

or

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

(Remember to release the previous value first)

The property setters/getters should be solely responsible for retaining/releasing the instance variable. What happens if you (or somebody else) changes the property setter to take a copy of the input instead of retaining it? In that case you are going to over-release the instance variable and leak the original object.

You are essentially sending a message which has private side-effects, and then using knowledge of those private details by releasing the instance variable on the next line. i.e. your code is the same as:

[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];

Even though you are in full control of the class, you should still adhere to the basic principles of abstraction and encapsulation. Leave the retaining/releasing of instance variables to the underlying property implementation.

鹤舞 2024-09-12 02:59:56

为什么不呢

tabBarController = [[UITabBarController alloc] init];

Why not

tabBarController = [[UITabBarController alloc] init];

?

情魔剑神 2024-09-12 02:59:56

您可以这样做,但更好的是不要在 init() 方法中使用这种隐式 setter 语法(因为您可能会覆盖 setter 并执行进一步的操作,如果对象是未完全初始化)。

只要这样做:

tabBarController = [[UITabBarController alloc] init];

You could do it this way, but better is to not use this implicit setter syntax in your init() method (because you might override the setter and do further stuff that might not work yet if the object is not fully initialized).

Just do:

tabBarController = [[UITabBarController alloc] init];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文