开发者

iphone @property(retain), init(), and standards

开发者 https://www.devze.com 2023-01-03 01:21 出处:网络
I\'m new to the memory management of the iphone and had a question about standards/correctness. My header file declares:

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 t开发者_开发技巧his.

Thanks


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.


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.


Why not

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

精彩评论

暂无评论...
验证码 换一张
取 消