Self syntax in iPhone development
What is the difference between the following two approaches for the self
syntax to access the object properties:-
Approach 1:-
self.effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
self.effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
开发者_高级运维
Approach 2:-
effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
effortView
is defined as a property, and synthesized, to the Class addressed as self
in Approach 1. Both of the approaches work.
I am using Xcode 4.0 iPhone SDK 4.3 on Mac 10.6.6.
Please enlighten me.
Thank you All
In the first syntax:
self.effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
self.effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
you are accessing both ivars through their accessor methods (usually, effortView
to get, setEffortView
to set).
In the second syntax:
effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
you are accessing the effortView
ivar directly (pointer assignment), while you are accessing effortTableView
through its property accessor.
The difference is that using an accessor you obtain additional behavior. Like, with the standard set
accessors generated by the @synthesize
keyword for a retain
property:
@property (nonatomic, retain) NSObject* property;
you get automatic retain count management (i.e., retain count will be automatically incremented on the assigned object; if the ivar had already a value, the object pointed to will have its retain count decreased). What this implies is that in your first example, you are causing 2 memory leaks. Indeed, (if the properties are declared as retain
property) assigning to them will increase their retain count; but [[alloc] init]
already gives back an object with a retain count of 1, so you don't need to increment it once more. Correct would be:
self.effortView = [[[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease];
self.effortView.effortTableView = [[[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped] autorelease];
Overall, properties make much easier to deal with retain count management and are the suggested way to go with it, but you have to be aware of their "retain count" semantics and account for that.
I would suggest this article as an interesting reading.
If the property is declared like this
@property (nonatomic, assign) EffortView *effortView;
both approaches are equivalent. In the case the property is declared like this
@property (nonatomic, retain) EffortView *effortView;
the code [[EffortView alloc] init...];
first generates a retained EffortView instance and then the 'assignment' self.effortView = ...
retains this instance again. Therefore to balance the retain count you have to release the generated instance.
The former uses the accessors methods generated by the synthesize statement.
The latter accesses the variable directly.
self.effortView
uses the accessor methods generated by @synthesize
to get and set the property, while effortView
accesses the instance variable directly. Inside the class where the property is defined, the difference is most important when considering the setter: it automatically takes care of memory management. So if you've done this:
@property (nonatomic, retain) EffortView *effortView;
then the two approaches have different results. Approach 1 leaks in this case, as the setter retains the object and you +alloc
it without a balanced -release
.
精彩评论