目标C强调属性与自我



我在玩标准示例拆分视图,当您在Xcode中选择拆分视图应用程序时会创建该视图,在添加一些字段后,我需要添加一些字段以在详细信息视图中显示它们。

然后发生了一些有趣的事情在原始示例中,主视图在详细视图中设置一个"detailItem"属性,详细视图显示该属性。

- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}

我理解它的作用,所以当我玩它的时候。我认为如果我使用self.detailItem而不是_detailItem,也会是一样的,因为它是类的属性。

然而,当我使用时

self.detailItem != newDetailItem

实际上,我陷入了一个循环,这个方法经常被调用,而我在模拟器中无法做任何其他事情。

我的问题是,下划线变量(ivar?)和属性之间的实际区别是什么?我在这里读到一些帖子,这似乎只是一些客观的C惯例,但实际上它产生了一些不同。

_property表示您正在直接访问该属性。

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

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

在实验过程中,您设置了一个无休止的循环,这就是模拟器没有响应的原因。

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

我想让你参考苹果公司关于申报财产的文件,了解财产、ivar等的独家新闻;但简单地说,声明的属性是为类提供访问器方法的一种简化方式。现在不必编写自己的访问器方法(就像我们在Objective-C 2.0之前所做的那样),它们是通过属性语法为您生成的。

属性基本上是编译器为给定实例变量生成setter

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

id detailItem = self.detailItem;

你在幕后做的是:

id detailItem = [self detailItem];

相同:

self.detailItem = otherDetailItem;

将是:

[self setDetailItem:otherDetailItem];

所以当你自己写二传手的时候。。由于您访问方法本身,因此您将进入一个无限循环。你可以自由地利用"自我"在类中使用表示法,而不是因为我上面描述的机制而重写setter或访问器。

我使用的类中的案例。简单地访问ivar的注释是,当我更改值时,您永远不知道在类内部更改值时需要发生什么。你是否有状态方面的东西应该通知某个代表状态发生了变化?但是,通常情况并非如此,只需使用即可。如果您决定在setter方法中使用一些魔术,那么您将确保在未来不必重构某些代码。

我将举一个例子(不启用ARC):

@property (nonatomic, retain) NSNumber* number;

如果你不合成它,你可以通过以下方式访问:

self.number= [NSNumber numberWithBool: YES];

在这种情况下,保留编号。如果你合成了它,并且不使用属性:

@synthesize number;

稍后在文件中:

number=[NSNUmber numberWithBool: YES];

您尚未使用该属性,因此不会保留该编号。这就造成了使用访问器和合成属性之间的相关区别。

最新更新