代码之家  ›  专栏  ›  技术社区  ›  Ryan Bavetta

访问器/获取器和延迟初始化

  •  2
  • Ryan Bavetta  · 技术社区  · 15 年前

    -(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 回复  |  直到 15 年前
        1
  •  3
  •   zoul    15 年前

    首先,为了你自己的利益不要太聪明。如果你想克服一些瓶颈,首先要测量并确保它真的存在。我相信两者 UIImage NSData 做一些内部延迟加载,这样你的代码就基本上没用了。第二,即使您真的想手动完成这样的操作,也可以尝试将缓存代码拆分为一个单独的类,这样就不会污染主类的代码。

    没有关于访问器的规则(至少据我所知没有),因为人们不会在访问器中进行太多的延迟加载。有时我会被懒惰造成的无休止的循环所吸引 [UIViewController loadView] 结合 [UIViewController view] ,但仅此而已。

        2
  •  2
  •   Shaggy Frog    15 年前

    没有什么是禁止的,但你肯定在写一些混乱的代码。本质上,这两个属性具有循环依赖关系。这很难阅读和调试。不清楚为什么要在“加载图像”之前“加载数据”,或者为什么还要在“加载数据”之前支持“加载图像”,或者这两个属性实际上是两个不同的东西。

        3
  •  0
  •   justin    15 年前

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

    具体来说,您可能希望从提供程序调用加载数据/映像,从awakeFromNib调用它(例如),然后加载程序运行并将数据加载到辅助线程(特别是在下载的情况下)。给数据提供者一个回调,通知视图映像已经就绪(通常使用协议)。一旦视图获取了未归档的图像,请使数据提供程序无效。

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