Iphone 访问器/获取器和延迟初始化
我有一个关于重写自动生成的访问器方法的问题。下面的方法不起作用(我相信),因为每个getter都引用了另一个getter。是否有一条规则规定访问器方法不应使用其他访问器方法,或者您只需单独注意这些情况Iphone 访问器/获取器和延迟初始化,iphone,objective-c,getter,accessor,lazy-initialization,Iphone,Objective C,Getter,Accessor,Lazy Initialization,我有一个关于重写自动生成的访问器方法的问题。下面的方法不起作用(我相信),因为每个getter都引用了另一个getter。是否有一条规则规定访问器方法不应使用其他访问器方法,或者您只需单独注意这些情况 -(UIImage *) image{ if(image == nil){ if(self.data == nil){ [self performSelectorInBackground: @selector(loadImage) withObje
-(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调用它(例如),然后加载程序运行并在辅助线程上加载数据(特别是在下载的情况下)。给数据提供程序一个回调,通知视图映像已就绪(通常使用协议)。视图获取未归档的图像后,使数据提供程序无效
最后,如果你在处理应用程序资源,“系统”会为你缓存一些资源,这样你就可以尝试在幕后处理已经优化的资源
简言之,它通常是可以的(例如,不延迟初始化)-但是这个特定的设计(如另一张海报所说)有一个循环依赖,应该最小化。我的问题是因为它是循环的。谢谢,我的意思是函数不停止线程-我已经更新了这个示例以派生后台线程(他们可能会在完成后发出回调或通知)pt1:关于更新:实际上最好让数据提供程序执行后台加载。在您的示例中,任何简单的成员访问都可以创建一个新线程(即,直到数据准备就绪)。因此,最好让数据提供程序跟踪这些模式(和线程安全),基于是否未请求,获取,加载-然后在图像不可用时调用数据提供程序加载图像。如果未请求,则在后台开始加载,如果获取,则忽略请求,否则断言,因为数据应在获取后传递。pt2:锁定回调/访问。使用使用时,您可能会在每次访问时创建一个后台请求-这可能意味着您正在请求多个后台加载,并在每次访问时创建一个新线程==您可能会有12个(或更多)线程通知数据提供程序加载数据。