访问器/获取器和延迟初始化
-
02-10-2019 - |
题
我有一个关于覆盖自动生成的访问器方法的问题。以下行不通(我相信),因为每个 getter 都引用另一个 getter。是否存在访问器方法不应使用其他访问器方法的规则,或者您是否只需要单独注意这些情况?
-(UIImage *) image{
if(image == nil){
if(self.data == nil){
[self performSelectorInBackground: @selector(loadImage) withObject: nil]
}else{
self.image = [UIImage imageWithData: self.data];
}
}
return image;
}
-(NSData *) data {
if(data == nil){
if(self.image == nil){
[self performSelectorInBackground: @selector(loadData) withObject: nil]
}else{
self.data = UIImageJPEGRepresentation(self.image, 0.85);
}
}
return data;
}
我必须强调,这里提供的图像使用只是一个示例,关于在这个特定示例中做什么的想法不如一般情况那么重要。
解决方案
首先,不要太聪明自己的利益。如果您想克服一些瓶颈,请先测量并确保它确实存在。我相信这两个 UIImage
和 NSData
进行一些内部的懒惰加载,以便您的代码本质上是没有用的。其次,即使您真的想手工做类似的事情,也尝试将缓存代码分为单独的类,以免污染主类的代码。
没有关于登录器的规则(至少我知道),因为人们在登录机中没有做太多懒惰的负载。有时我会被懒惰造成的无尽循环所抓住 [UIViewController loadView]
结合 [UIViewController view]
, ,但仅此而已。
其他提示
没有什么禁止的,但是您肯定会编写一些令人困惑的代码。本质上,这两个特性具有圆形依赖性。这很难阅读和调试。目前尚不清楚为什么您要在“加载图像”之前要“加载数据”,或者为什么您也想在“加载数据”之前支持“加载图像”,或者真正如何处理两个属性确实是两件事。
您在本示例中实际执行的操作可能需要很长时间才能加载;最好保证它是线程安全的。
此外,如果您使数据对象成为一个真正的数据提供者(通常使用协议),与类分开,并使图像容器暴露它正在处理延迟加载的对象(这可能会引起某些人的强烈抗议),那就更好了人们)。
具体来说,您可能想从提供者调用加载数据/图像,从 awakeFromNib 调用它(例如) - 然后加载器运行并在辅助线程(特别是在辅助线程)上加载数据。如果已下载)。给数据提供者一个回调,通知视图图像已准备好(通常使用协议)。一旦视图获取未归档的图像,数据提供者就会失效。
最后,如果您正在处理应用程序资源,“系统”将为您缓存其中的一些资源,因此您将尝试针对幕后已经优化的内容进行工作。
简而言之,通常没问题(例如不是延迟初始化) - 但这种特定设计(正如另一位海报所说)具有应该最小化的循环依赖性。