self
语法访问对象属性的以下两种方法之间有什么区别: -
方法1: -
self.effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
self.effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
方法2: -
effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
effortView
被定义为属性,并在方法1 中合成为self
的类。这两种方法都有效。
我在Mac 10.6.6上使用Xcode 4.0 iPhone SDK 4.3。
请赐教。
谢谢大家
答案 0 :(得分:5)
在第一种语法中:
self.effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
self.effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
您通过其访问者方法访问这两个ivars(通常effortView
获取,setEffortView
设置)。
在第二种语法中:
effortView = [[EffortView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
effortView.effortTableView = [[UITableView alloc]initWithFrame:CGRectMake(25, 25, 300, 420) style:UITableViewStyleGrouped];
当您通过其属性访问者访问effortView
时,您正在直接访问effortTableView
ivar(指针赋值)。
不同之处在于使用访问器可以获得其他行为。例如,使用set
关键字为@synthesize
属性生成的标准retain
访问者:
@property (nonatomic, retain) NSObject* property;
您将获得自动保留计数管理(即,保留计数将在指定的对象上自动递增;如果ivar已经有值,则指向的对象将使其保留计数减少)。这意味着在您的第一个示例中,您导致2次内存泄漏。实际上,(如果属性被声明为retain
属性)分配它们将增加它们的保留计数;但[[alloc] init]
已经返回一个保留计数为1的对象,因此您不需要再次递增它。正确的是:
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];
总的来说,属性更容易处理保留计数管理,并且是建议的方法,但你必须知道它们的“保留计数”语义并解释它。
我建议将this article作为一个有趣的阅读材料。
答案 1 :(得分:1)
如果声明属性如此
@property (nonatomic, assign) EffortView *effortView;
两种方法都是等价的。在属性声明为的情况下
@property (nonatomic, retain) EffortView *effortView;
代码[[EffortView alloc] init...];
首先生成一个保留的EffortView实例,然后'赋值'self.effortView = ...
再次保留此实例。因此,要平衡保留计数,您必须释放生成的实例。
答案 2 :(得分:0)
前者使用synthesize语句生成的访问器方法。
后者直接访问变量。
答案 3 :(得分:0)
self.effortView
使用@synthesize
生成的访问器方法来获取和设置属性,而effortView
直接访问实例变量。在定义属性的类中,在考虑setter时,差异是最重要的:它会自动处理内存管理。所以,如果你这样做了:
@property (nonatomic, retain) EffortView *effortView;
然后这两种方法有不同的结果。在这种情况下,方法1会泄漏,因为设置者会保留对象而您+alloc
没有平衡的-release
。