文档章节

swift 延迟加载

孙哲
 孙哲
发布于 2015/03/04 17:26
字数 706
阅读 267
收藏 4

 iOS Developer      

Lazy Initialization with Swift

22 Jun 2014 •            

Lazy initialization (also sometimes called lazy instantiation, or  lazy loading) is a technique for delaying the creation of an object or  some other expensive process until it’s needed. When programming for  iOS, this is helpful to make sure you utilize only the memory you need  when you need it.

This technique is so helpful, in fact, that Swift added direct support for it with the lazy attribute.

To understand why this is useful, let's first go over the old way of creating lazy properties.


The Old Way

In Objective-C, if you had a mutable array property you wanted lazily initialized, you’d have to write this:

@property (nonatomic, strong) NSMutableArray *players; 
- (NSMutableArray *)players {     
    if (!_players) {         
        _players = [[NSMutableArray alloc] init];     
    }     
    return _players; 
}

To people new to Objective-C, this presents a few different learning  curves. First of all, you need to know that the method name has to  exactly match the property name. If you misspelled the method name, this  would silently fail and players would be nil when you tried to access it.

You also need to know the _players instance variable was  created for you automatically when your property was synthesized.  Before Xcode 4.4, you had to manually synthesize your variable using the  @synthesize keyword, like so:

@synthesize players; // - or - @synthesize players = _players;

Which would tell you that the instance variable used for the players property is _players.  Nowadays Xcode handles synthesizing your properties for you. If you  didn’t know that, then using the underscore before the property name  might not be immediately obvious.


The Swift Way

Now in Swift, this can all be simplified down to one line:

lazy var players = [String]()

Simple, concise, and straight to the point.

Keep in mind you do need to declare your lazy property using the var keyword, not the let keyword, because constants must always have a value before initialization completes.

If you wanted to add logic to your lazy initialization, Swift makes  this easy by letting you define a closure after your lazy property:

lazy var players: [String] = {         
    var temporaryPlayers = [String]()         
    temporaryPlayers.append("John Doe")         
    return temporaryPlayers         
}()

If you prefer, you can also lazily initiate your property using an instance method:

lazy var players: [String] = self.initialPlayers() func initialPlayers() -> [String] {     
    var players = ["John Doe"]     
    return players 
}

Or a class method:

class TestClass {     
    lazy var players = TestClass.initialPlayers()     
    class func initialPlayers() -> [String] {         
        var players = ["John Doe"]         
        return players     
    } 
}

But people will most likely prefer using the new closure mechanic, as it keeps the logic near the property declaration.


When should I use lazy initialization?

One example of when to use lazy initialization is when the initial value for a property is not known until after the object is initialized.

For example, if you have a Person class and a personalizedGreeting property. The personalizedGreeting  property can be lazily instantiated after the object is created so it  can contain the name of the person. Here’s a quick example:

class Person {     
    var name: String     
    lazy var personalizedGreeting: String = {        
         [unowned self] in         
        return "Hello, \(self.name)!"         
    }()    
 
    init(name: String) {         
        self.name = name     
    } 
}

(Note that we had to say [unowned self] in here to prevent a strong reference cycle)

When you initialize a person, their personal greeting hasn’t been created yet:

let person = Person(name: "John Doe") // person.personalizedGreeting is nil

But when you attempt to print out the personalized greeting, it’s calculated on-the-fly:

NSLog(person.personalizedGreeting) 
// personalizedGreeting is calculated when used 
// and now contains the value "Hello, John Doe!"

Another good time to use lazy initialization is when the initial value for a property is computationally intensive.

For example, if you have an object that performs some really intense  algorithm to determine the number of faces in a picture, make the numberOfFaces property lazily initialized.

Or if you had a class that calculates several different large  numbers, you would want to make sure they’re only calculated on-demand:

class MathHelper {     
    lazy var pi: Double = {         
        // Calculate pi to a crazy number of digits         
        return resultOfCalculation         
    }() 
}

Conclusion

Direct support for lazy property initialization is just one of the  many great features of Swift. In the next few months, I'll cover more  great features and shortcuts. Stay tuned!



本文转载自:http://mikebuss.com/2014/06/22/lazy-initialization-swift/?utm_source=tuicool

共有 人打赏支持
孙哲
粉丝 18
博文 30
码字总数 2877
作品 0
徐汇
高级程序员
swift 中的 lazy

概念 延迟加载是初始化很常用的性能优化方式,尤其是在一些对象的属性十分复杂的时候,默认全部初始化会耗费不少时间,影响性能。还有一些特定环境下才使用的对象,更是浪费资源。所以有些时...

Inlight先森
2017/12/20
0
0
swift懒加载(lazy load)VS OC懒加载

懒加载可以让你不用关心变量的创建时机,等到真正使用的时候才去创建并且能保证在使用的时候已经初始化完毕,在一定程度上可以提高性能。 OC懒加载的原理: 重写变量的 getter 方法,在gette...

zh_iOS
2016/12/29
0
0
AppCode 2017.1 RC 版发布,Bug 修复版本

AppCode 2017.1 RC 版今天发布了,版本号为 171.3890.2 下面的问题已在该版本中修复: Swift 中的具有错误处理意图的回归 (OC-15061) 在 Swift中 查找用法的问题 (OC-13248) 重新构建标记后,...

局长
2017/03/16
614
2
【swift 关键词】让我们牢记swift中的一些关键字用途

好记性不如烂笔头 学习swift 原英文版本 学习swift 翻译中文版 swift数据类型与oc比较 进入 退出swift 第一个关键字guard inout unowned lazy willSet didSet get set mutating Subscripts C...

创意总监
2016/05/25
82
0
Swift 下用 lazy 让方法只被调用一次

在写 Swift 的过程中,我们会经常使用 lazy 来延迟一个对象的初始化。今天我发现了一个关于 lazy 的新的用法,也就用 lazy 来达到使「方法」只被调用一次,而不仅限于用在「对象」上。 lazy...

I'm TualatriX
05/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

arcgis jsapi接口入门系列:总览

开发环境: arcgis jsapi版本4.9 由于我们这套代码是基于vue,webpack开发的,会有少数vue代码,但总体不影响 里面还有些我们公司的js库和html css,给出的代码不能百分百直接运行,主要还是...

canneljls
21分钟前
1
0
月薪80k阿里架构师漫谈他是如何从一名小码农走到架构师的

01 刚当程序员时,我是属于那种勤勤恳恳类型的员工,工作态度用认真来形容不为过,每天我几乎是团队里最早到公司,又最晚下班的一个。而组员张工一般情况下都是准时上下班的,即使项目进度比...

Java填坑之路
23分钟前
1
0
oracle的resetlogs机制浅析

oracle的resetlogs机制浅析 alter database open resetlogs 这个命令我想大家都很熟悉了,那有没有想过这个resetlogs选项为什么要用?什么时候用? 它的原理机制是什么?他都起哪些作用? 我...

突突突酱
25分钟前
1
0
JAVA 获取两个日期间的所有日期

public static List<String> getDates(String startDate, String endDate){ List<String> dates = new ArrayList<>(); try { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); Dat......

尘叙缘
31分钟前
2
0
Innodb中的事务隔离级别和锁的关系

#一次封锁or两段锁? 因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会用到哪些数据,然后全部锁住,在方法运行之后,再全部解锁。...

Skqing
45分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部