懒加载
2017-01-10 本文已影响13人
JanuaryMei
懒加载
当实例化一个对象可能耗费很多资源的,或者需要只配置一次并且有一些配置方法需要调用,而且你还不想弄乱这些方法。
在这个情况下,我们可以选择使用重载属性的 getter 方法来做 lazy 实例化。通常这种操作的模板像这样:
- (NSDateFormatter *)dateFormatter {
if (!_dateFormatter) {
_dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSSS"];
}
return _dateFormatter;
}
即使在一些情况下这是有益的,但是我们仍然建议你在决定这样做之前经过深思熟虑,事实上这样是可以避免的。下面是使用 延迟实例化的争议。
- getter 方法不应该有副作用。在使用 getter 方法的时候你不要想着它可能会创建一个对象或者导致副作用,事实上,如果调用 getter 方法的时候没有涉及返回的对象,编译器就会放出警告:getter 不应该产生副作用
- 你在第一次访问的时候改变了初始化的消耗,产生了副作用,这回让优化性能变得困难(以及测试)
- 这个初始化可能是不确定的:比如你期望属性第一次被一个方法访问,但是你改变了类的实现,访问器在你预期之前就得到了调用,这样可以导致问题,特别是初始化逻辑可能依赖于类的其他不同状态的时候。总的来说最好明确依赖关系。
- 这个行为不是 KVO 友好的。如果 getter 改变了引用,他应该通过一个 KVO 通知来通知改变。当访问 getter 的时候收到一个改变的通知很奇怪。