文档章节

swift 延迟加载

孙哲
 孙哲
发布于 2015/03/04 17:26
字数 706
阅读 265
收藏 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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JS:异步 - 面试惨案

为什么会写这篇文章,很明显不符合我的性格的东西,原因是前段时间参与了一个面试,对于很多程序员来说,面试时候多么的鸦雀无声,事后心里就有多么的千军万马。去掉最开始毕业干了一年的Jav...

xmqywx
今天
0
0
Win10 64位系统,PHP 扩展 curl插件

执行:1. 拷贝php安装目录下,libeay32.dll、ssleay32.dll 、 libssh2.dll 到 C:\windows\system32 目录。2. 拷贝php/ext目录下, php_curl.dll 到 C:\windows\system32 目录; 3. p...

放飞E梦想O
今天
0
0
谈谈神秘的ES6——(五)解构赋值【对象篇】

上一节课我们了解了有关数组的解构赋值相关内容,这节课,我们接着,来讲讲对象的解构赋值。 解构不仅可以用于数组,还可以用于对象。 let { foo, bar } = { foo: "aaa", bar: "bbb" };fo...

JandenMa
今天
1
0
OSChina 周一乱弹 —— 有人要给本汪介绍妹子啦

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享水木年华的单曲《中学时代》@小小编辑 手机党少年们想听歌,请使劲儿戳(这里) @须臾时光:夏天还在做最后的挣扎,但是晚上...

小小编辑
今天
21
5
centos7安装redis及开机启动

配置编译环境: sudo yum install gcc-c++ 下载源码: wget http://download.redis.io/releases/redis-3.2.8.tar.gz 解压源码: tar -zxvf redis-3.2.8.tar.gz 进入到解压目录: cd redis-3......

hotsmile
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部