我正在使用在Xcode中选择拆分视图应用程序时创建的标准样本拆分视图,添加几个字段后,我需要添加一些字段以在详细视图中显示它们.
在原始样本中发生了一些有趣的事情,主视图在详细视图中设置了"detailItem"属性,详细视图显示了它.
- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
Run Code Online (Sandbox Code Playgroud)
我理解那是什么以及所有,所以当我在玩它时.我认为如果不使用_detailItem我会使用self.detailItem,因为它是类的属性.
但是,当我使用
self.detailItem != newDetailItem
Run Code Online (Sandbox Code Playgroud)
我实际上卡在一个循环中,这个方法经常被调用,我不能在模拟器中做任何其他事情.
我的问题是,下划线变量(ivar?)和属性之间的实际差异是什么?我在这里看了一些帖子似乎只是一些客观的C约定,但它实际上有所不同.
这些属性基本上是编译器为给定实例变量生成setter和getter的一种方式.
所以当你使用类似的东西:
id detailItem = self.detailItem;
Run Code Online (Sandbox Code Playgroud)
你在幕后做的是:
id detailItem = [self detailItem];
Run Code Online (Sandbox Code Playgroud)
同样的:
self.detailItem = otherDetailItem;
Run Code Online (Sandbox Code Playgroud)
将会:
[self setDetailItem:otherDetailItem];
Run Code Online (Sandbox Code Playgroud)
所以当你自己编写setter时,你会进入一个无限循环,因为你自己访问方法本身.你可以自由地利用'自我'.因为我上面描述的机制,你的班级中的符号,而不是当你覆盖了setter或accessor时.
在我使用的类中的案例.简单地访问ivar的注意事项是当我更改值时,你不会在课堂内知道更改值时需要发生什么.你有什么状态可以通知某个代表状态发生了变化吗?但通常情况并非如此,只需使用.表示你确定将来如果你决定在你的setter方法中做一些魔术,你将不必重构一些代码.