文档章节

swift 延迟加载

孙哲
 孙哲
发布于 2015/03/04 17:26
字数 706
阅读 264
收藏 4
点赞 0
评论 0

 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!



© 著作权归作者所有

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

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

Inlight先森 ⋅ 2017/12/20 ⋅ 0

swift懒加载(lazy load)VS OC懒加载

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

zh_iOS ⋅ 2016/12/29 ⋅ 0

AppCode 2017.1 RC 版发布,Bug 修复版本

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

局长 ⋅ 2017/03/16 ⋅ 2

【swift 关键词】让我们牢记swift中的一些关键字用途

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

创意总监 ⋅ 2016/05/25 ⋅ 0

Swift 下用 lazy 让方法只被调用一次

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

I'm TualatriX ⋅ 05/10 ⋅ 0

iOS 的 HUD--ZKProgressHUD

iOS App 上易于使用的 HUD 运行环境 iOS 8.0 + Xcode 8 + Swift 3.0 + 安装 CocoaPods 你可以使用 CocoaPods 安装 ,在你的 中添加: platform :ios, '8.0'use_frameworks! target 'MyApp' d......

Swift王叔叔 ⋅ 2017/03/15 ⋅ 0

swift中修饰词,fileprivate、private、internal、public 、open 及lazy的使用

在swift开发语言中,访问修饰符就fileprivate、private、internal、public 、open这五种。其中fileprivate和open是swift3中添加的;由于之前的swift对于访问控制是基于文件的,在swift3中就出...

媛美一生 ⋅ 2016/09/29 ⋅ 0

深入理解iOS App的启动过程

前言 启动时间是衡量应用品质的重要指标。 本文首先会从原理上出发,讲解iOS系统是如何启动App的,然后从main函数之前和main函数之后两个角度去分析如何优化启动时间。 准备知识 Mach-O 哪些...

黄文臣 ⋅ 2017/10/23 ⋅ 0

Swift4.0开发笔记

目录 1、ATS配置 2、状态栏全局变亮白 3、懒加载 4、内存泄漏 5、常用的第三方库 6、反射机制 7、运行时 8、MD5加密 9、聊天界面 10、多线程GCD 11、 启动图尺寸大小 1、ATS配置 App 网络htt...

星星编程 ⋅ 2017/11/03 ⋅ 0

又立 Flag ?Swift 5 称必定能实现 ABI 稳定

前几日,Swift 语言开发项目组主管 Ted Kremenek 发邮件称,Swift 4 更新工作已基本完结,将在今年晚些时候正式发布。同时,Swift 5 的开发工作即将展开,鼓励开发者提交提案。 Kremenek 在 ...

王练 ⋅ 2017/08/18 ⋅ 18

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

金山WPS发布了Linux WPS Office

导读 近日,金山WPS发布了Linux WPS Office中文社区版新版本,支持大部分主流Linux系统,功能更加完善,兼容性、稳定性大幅度提升。本次更新WPS将首次在Linux提供专业办公文件云存储服务,实...

问题终结者 ⋅ 昨天 ⋅ 0

springboot2输出metrics到influxdb

序 本文主要研究一下如何将springboot2的metrics输出到influxdb maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo......

go4it ⋅ 昨天 ⋅ 0

微信小程序 - 选择图片显示操作菜单

之前我分享过选择图片这个文章,但是我在实际开发测试使用中发现一个问题在使用 wx.chooseImage 选择照片显示出第一格是拍照,后面是相册里的图片。这种实现之前说过了,效果如下。 但是你从...

hello_hp ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部