遅延初期化(Lazy initialization/ Lazy loading)はプロパティー/メンバー変数の初期化処理を、メソッド呼び出し時まで先延ばしするためのテクニックです。
GUIプログラミングの世界では割とよく使われている技法で、アプリの起動や画面の初期化を高速化することが出来ます。
/** Lazy.h */
@interface Lazy : NSObject
@property (nonatomic) NSMutableDictionary *dictionary;
@property (nonatomic) NSMutableArray *array;
+(NSCharacterSet *)separatorSet;
@end
/** Lazy.m */
@implementation Lazy
// 遅延初期化
-(NSMutableDictionary *)dictionary {
if (!_dictionary) { // 初回呼び出し時はnilなのでif文内の処理が実行される
// 二回目の呼び出しでは呼ばれない
_dictionary = [NSMutableDictionary dictionary];
}
return _dictionary;
}
// 遅延初期化(簡略化版)
-(NSArray *)array {
return _array ?: (_array = [NSMutableArray array]);
}
// 遅延初期化(クラスメソッド版)
+(NSCharacterSet *)separatorSet {
static NSCharacterSet *set = nil;
return set ?: (set = [NSCharacterSet characterSetWithCharactersInString:@",|"]);
}
@end
遅延初期化のメリットは以下の様な初期化処理をプロパティ呼び出し時/メソッド実行時まで先送りさせることが出来る点です。
@implementation Lazy
-(instancetype)init {
if (self = [super init]) {
// このタイミングでの初期化処理が不要になる・先送りできる
_dictionary = [NSMutableDictionary dictionary];
_array = [NSMutableArray array];
}
return self;
}
@end
インスタンス変数の初期化のコストが高くなればなるほど、遅延初期化のメリットは大きくなります。滅多に呼ばれないプロパティ/メソッドを遅延初期化するようにすると非常に効果的です。
アプリの画面初期化がもたつくような場合に取り入れてみると良いでしょう。
ただし、頻繁に呼び出されるプロパティ/メソッドに関しては、遅延初期化に伴うメンバー変数のNULL/nilチェックが余計な処理コストとなってしまう恐れがありますので、注意してください。 そのようなケースでは従来通り、コンストラクタやイニシャライザ内での初期化をオススメします。