目标C强调财产与自我

时间:2012-12-08 10:57:25

标签: objective-c

我正在使用在Xcode中选择拆分视图应用程序时创建的标准样本拆分视图,添加几个字段后,我需要添加一些字段以在详细视图中显示它们。 / p>

发生了一些有趣的事情 在原始样本中,主视图在详细视图中设置“detailItem”属性,详细视图显示它。

- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
    _detailItem = newDetailItem;

    // Update the view.
    [self configureView];
}

我明白这是做什么的,所以当我在玩它时。我认为如果不使用_detailItem我会使用self.detailItem,因为它是类的属性。

然而,当我使用

self.detailItem != newDetailItem

我实际上卡在一个循环中,这个方法经常被调用,我不能在模拟器中做任何其他事情。

我的问题是,下划线变量(ivar?)和属性之间的实际差异是什么? 我在这里阅读了一些帖子似乎只是一些客观的C约定,但实际上它有所不同。

4 个答案:

答案 0 :(得分:41)

_property表示您正在直接访问该物业。

self.property表示您正在使用访问者。

在你的情况下,在你调用它的setter方法中,创建一个递归调用。

答案 1 :(得分:6)

在您的实验过程中,您已经设置了无限循环,这就是模拟器无响应的原因。

self.detailItem调用setDetailItem:的范围内以递归方式调用setDetailItem:,因为您的类为属性detailItem实现了自定义setter方法。

我会引用你关于属性,ivars等scoop的声明属性的Apple documentation;但简单地说,声明的属性是为您的类提供访问器方法的简化方法。它们不是必须编写您自己的访问器方法(就像我们在Objective-C 2.0之前所做的那样),而是通过属性语法为您生成它们。

答案 2 :(得分:5)

这些属性基本上是编译器为给定实例变量生成 setter getter 的一种方式。

所以当你使用类似的东西时:

id detailItem = self.detailItem;

你在幕后做的是:

id detailItem = [self detailItem];

同样的:

self.detailItem = otherDetailItem;

将是:

[self setDetailItem:otherDetailItem];

所以当你自己编写setter时,你会进入一个无限循环,因为你自己访问方法本身。 你可以自由地利用'自我'。因为我上面描述的机制,你的班级中的符号,而不是当你覆盖了setter或accessor时。

我使用的课程中的案例。简单地访问ivar的注意事项是当我更改值时,你不会在课堂内知道更改值时需要发生什么。你有什么状态可以通知某个代表状态发生了变化吗?但通常情况并非如此,只需使用。表示你确定将来你不必重构某些代码,如果你决定在你的setter方法中做一些魔术。

答案 3 :(得分:2)

我将做一个例子(没有启用ARC):

@property (nonatomic, retain) NSNumber* number;

如果你没有合成它,你可以这样访问它:

self.number= [NSNumber numberWithBool: YES];

这种情况下,数字会被保留。如果您合成它而不使用该属性:

@synthesize number;

稍后在文件中:

number=[NSNUmber numberWithBool: YES];

您尚未使用该属性,因此不会保留该数字。这在使用访问器和合成属性之间存在相关差异。