我在我的属性上使用惰性实例化,以尽可能快地创建和使用我的类。要做到这一点,我写了很多空的'像这样的吸气剂:
- (VMPlacesListFilter *)currentFilter
{
if (!_currentFilter) {
_currentFilter = [[VMPlacesListFilter alloc] init];
}
return _currentFilter;
}
它们都是相同的:如果实例变量是nil
,则在属性的类上调用-alloc
和-init
,然后返回实例变量。非常普遍和直截了当。
如果我不是自己创建这个getter,Objective-C的自动合成会为我创建一个getter,它只返回返回的部分(如果实例变量是{{,则不会初始化对象) 1}})。
有没有办法避免编写这个样板代码?
答案 0 :(得分:2)
不,如果你真的想要进行延迟初始化,我担心它没有好办法。就个人而言,我通常会为那些真正耗时或内存密集的东西(例如,加载图像或视图控制器)保存延迟初始化,并在init
中初始化廉价的东西(如简单的数据结构或模型对象)。
- (instancetype) init {
self = [super init];
if( self ) {
_cheapThing1 = [NSMutableArray array];
_cheapThing2 = [[MyModelObject alloc] init];
}
return self;
}
- (ExpensiveThing*) expensiveThing
{
if( _expensiveThing == nil ) {
_expensiveThing = [[ExpensiveThing alloc] init];
}
return _expensiveThing;
}
除非您从磁盘或网络加载某些内容,否则我不会过多担心初始化时间。当然,简介它。
我知道这是一个Objective-C问题,但值得注意的是Swift内置了懒惰的初始化。
lazy var currentFilter = VMPlacesListFilter()
答案 1 :(得分:2)
首先,我完全赞同@zpasternack" lazy load"不应该被滥用。但是,使用Objective-C运行时的强大功能,自动生成setter和getter是完全可行的。实际上,CoreData
正在这样做。
无论如何,我提出了一些实现名为LazyClass
的类的愚蠢代码,您可以在其中声明动态属性,如lazyArray
(见下文)。使用动态方法解析,首次访问该属性时,将自动添加调用相应类的默认+alloc
和-init
方法的getter上课。所有基础实例变量都存储在名为NSMutableDictionary
的{{1}}中。当然,您也可以通过运行时API来操作ivars,但使用字典可以节省一些工作。
请注意,此实现仅显示其工作原理的基本概念。它缺乏错误检查,不应该发货。
<强> LazyClass.h 强>
myVars
<强> LazyClass.m 强>
@interface LazyClass : NSObject
@property NSMutableDictionary *myVars;
// lazily initialized property
@property NSArray *lazyArray;
@end
答案 2 :(得分:1)
如果它困扰你的冗长,我想你可以压缩只需要使用三元运算符进行单行初始化的惰性初始化器:
- (VMPlacesListFilter *)currentFilter
{
return _currentFilter ? : (_currentFilter = [[VMPlacesListFilter alloc] init]);
}
免责声明:我不这样做,但有趣的事情可以做到