访问者/获取者和惰性初始化

时间:2010-09-14 06:35:37

标签: iphone objective-c getter accessor lazy-initialization

我有一个关于覆盖自动生成的访问器方法的问题。以下不起作用(我相信),因为每个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;
}

我必须强调,这里提供的图像使用是一个例子,关于在这个特定例子中做什么的想法不如一般情况那么重要。

3 个答案:

答案 0 :(得分:3)

首先,不要为了自己的利益而过于聪明。如果你想克服一些瓶颈,首先要衡量并确保它真的存在。我相信UIImageNSData都会进行一些内部延迟加载,因此您的代码可能基本上没用。其次,即使您真的想手动执行此类操作,也可以尝试将缓存代码拆分为单独的类,这样就不会污染主类的代码。

没有关于访问者的规则(至少我不知道),因为人们在访问器中没有做太多的延迟加载。有时我会被懒惰的[UIViewController loadView][UIViewController view]组合引起的无休止的循环所困扰,但这就是它。

答案 1 :(得分:2)

没有什么可以禁止它,但你肯定在编写一些令人困惑的代码。实质上,这两个属性具有循环依赖性。这很难读取和调试。目前还不清楚为什么你想在“加载图像”之前“加载数据”,或者为什么你还想在“加载数据”之前支持“加载图像”,或者真的是如何在两个属性之前真的是两件事。

答案 2 :(得分:0)

您在此示例中实际执行的操作可能需要很长时间才能加载;最好确保它是线程安全的。

此外,如果您使数据对象成为真正的数据提供者(通常使用协议),与类分开,并使图像容器暴露它处理延迟加载的对象(这可能会导致一些人的抗议)。

具体来说,您可能希望从提供程序调用加载数据/映像,从awakeFromNib调用它(例如) - 然后加载器运行并在辅助线程上加载数据(特别是如果下载)。为数据提供程序提供回调,以通知视图图像已准备就绪(通常使用协议)。一旦视图获取未归档的图像,则使数据提供者无效。

最后,如果您正在处理应用资源,那么'系统'会为您缓存部分内容,以便您尝试使用已经在幕后优化的内容。

简而言之,它通常是正常的(例如,不是懒惰的初始化) - 但是这个特定的设计(如另一张海报所说)具有循环依赖性,应该最小化。