iPhone开发中的自我语法

时间:2011-06-02 08:44:41

标签: iphone objective-c ios ios4

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。

请赐教。

谢谢大家

4 个答案:

答案 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