自定义设置器中 if 语句的目的是什么?我在示例代码中经常看到这个例程。提供使用 ARC,为什么还要检查相等性?
- (void)setPhotoDatabase:(UIManagedDocument *)photoDatabase
{
if (_photoDatabase != photoDatabase) {
_photoDatabase = photoDatabase;
...
}
}
自定义设置器中 if 语句的目的是什么?我在示例代码中经常看到这个例程。提供使用 ARC,为什么还要检查相等性?
- (void)setPhotoDatabase:(UIManagedDocument *)photoDatabase
{
if (_photoDatabase != photoDatabase) {
_photoDatabase = photoDatabase;
...
}
}
重要的部分通常是更改之后的内容(中的内容...
):分配新值后的副作用,这可能非常昂贵。
限制这些更改以避免触发不必要且可能非常昂贵的副作用是一个好主意。假设您更改了一个文档,那么您可能需要更改与该文档相关的大部分用户界面,以及模型更改。
检查条件后,大量不必要的/更改工作可能会短路,最终可能会避免进行不必要的更改。
这种不必要的副作用很容易使您的应用程序在 CPU、绘图、对象创建、写入磁盘方面的实际工作黯然失色——几乎任何事情。
信不信由你,许多应用程序确实执行了大量不必要的工作,即使它们设计得非常好。基于视图的渲染系统中的绘图和 ui 更新可能是我能想到的最好的例子。在该领域中,可以实施大量细节来最大程度地减少冗余绘图。
覆盖和实现自定义设置器的主要原因之一是执行附加代码以响应属性的更改。如果属性实际上没有改变,为什么要执行该代码?
答案通常在...
您注释掉的部分中:当那里什么都没有时,代码没有意义。然而,在那个地方有一个典型的事情是你自己的代表的某种通知,像这样:
[myDelegate photoDatabaseDidChanged:photoDatabase];
photoDatabase
除非确实发生了变化,否则不应调用此方法。调用可能很昂贵,从“昂贵”到“非常昂贵”,取决于代表的实际工作。它可以使用新库中的图像更新屏幕,也可以将新图像保存到云中。如果不需要报告更改,您可能会浪费 CPU 周期以及电池和网络带宽。您的代码无法知道委托将要做什么,因此您需要避免回调,除非确实发生了更改。
如果检查相等性,则可以防止传递给方法的参数的冗余分配。
这样,如果您的示例方法中的 photoDatabase 没有更改,您就可以避免在括号内执行所有代码的成本(即使它很小)。
Ex(扩展您的示例):
- (void)setPhotoDatabase:(UIManagedDocument *)photoDatabase
{
if (_photoDatabase != photoDatabase)
{
_photoDatabase = photoDatabase;
// do stuff
// do more stuff
// do even more stuff
// do something really expensive
}
}
从示例中可以看出,如果您首先检查 photoDatabase 是否不等于传入的内容,您可以退出该方法而不运行不必要的其他代码。