文档章节

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
博文 31
码字总数 3368
作品 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
653
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

没有更多内容

加载失败,请刷新页面

加载更多

jquery

语法 描述 实例 $("*") 选取所有元素 在线实例 $(this) 选取当前 HTML 元素 在线实例 $("p.intro") 选取 class 为 intro 的 <p> 元素 在线实例 $("p:first") 选取第一个 <p> 元素 在线实例 ...

mskk
4分钟前
0
0
微信红包设计方案

前言 微信红包一经推出,春节期间微信用户红包总发送量达80.8亿,红包峰值40.9w/秒,在如此量级下,系统设计存在各种变数,稍有闪失会功亏一篑。 红包系统 红包系统有三部分组成:信息流,业...

春哥大魔王的博客
14分钟前
0
0
微信开发-正式号的配置

1、设置相关 业务域名的设置(不设置的话,相关页面会显示防欺诈盗号信息提示) JS接口安全域名设置 网页授权域名设置 注意:以上三个设置中都有下载文件的提示,此文件内容一样,下载一个即可...

Code辉
20分钟前
1
0
微服务之Eureka服务发现

当调用API或者发起网络通信的时候,无论如何我们都要知道被调用方的IP和服务端口,大部分情况是通过域名和服务端口,事实上基于DNS的服务发现,因为DNS缓存、无法自治和其他不利因素的存在,...

架构师springboot
20分钟前
0
0
spring boot2 admin login

版本: admin server 配置 admin client 配置 参考资料

showlike
22分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部