【iOS】Swift LAZY 修饰符和 LAZY 方法
延时加载或者说延时初始化是很常用的优化方法,在构建和生成新的对象的时候,内存分配会在运行时耗费不少时间,如果有一些对象的属性和内容非常复杂的话,这个时间更是不可忽略。另外,有些情况下我们并不会立即用到一个对象的所有属性,而默认情况下初始化时,那些在特定环境下不被使用的存储属性,也一样要被初始化和赋值,也是一种浪费。
在其他语言 (包括 Objective-C) 中延时加载的情况是很常见的。我们在第一次访问某个属性时,判断这个属性背后的存储是否已经存在,如果存在则直接返回,如果不存在则说明是首次访问,那么就进行初始化并存储后再返回。这样我们可以把这个属性的初始化时刻推迟,与包含它的对象的初始化时刻分开,以达到提升性能的目的。以 Objective-C 举个例子 (虽然这里既没有费时操作,也不会因为使用延时加载而造成什么性能影响,但是作为一个最简单的例子,可以很好地说明问题):
// ClassA.h
@property (nonatomic, copy) NSString *testString;
// ClassA.m
- (NSString *)testString {
if (!_testString) {
_testString = @"Hello";
NSLog(@"只在首次访问输出");
}
return _testString;
}
在初始化 ClassA
对象后,_testString
是 nil
。只有当首次访问 testString
属性时
getter 方法会被调用,并检查如果还没有初始化的话,就进行赋值。为了方便确认,我们还在赋值时打印了一句 log。我们之后再多次访问这个属性的话,因为 _testString
已经有值,因此将直接返回。
在 Swift 中我们使用在变量属性前加 lazy
关键字的方式来简单地指定延时加载。比如上面的的代码我们在 Swift 中重写的话,会是这样:
class ClassA {
lazy var str: String = {
let str = "Hello"
print("只在首次访问输出")
return str
}()
}
我们在使用 lazy
作为属性修饰符时,只能声明属性是变量。另外我们需要显式地指定属性类型,并使用一个可以对这个属性进行赋值的语句来在首次访问属性时运行。如果我们多次访问这个实例的 str
属性的话,可以看到只有一次输出。
为了简化,我们如果不需要做什么额外工作的话,也可以对这个 lazy
的属性直接写赋值语句:
lazy var str: String = "Hello"
相比起在 Objective-C 中的实现方法,现在的 lazy 使用起来要方便得多。
另外一个不太引起注意的是,在 Swift 的标准库中,我们还有一组 lazy
方法,它们的定义是这样的:
func lazy<S : SequenceType>(s: S) -> LazySequence<S>
func lazy<S : CollectionType where S.Index : RandomAccessIndexType>(s: S)
-> LazyRandomAccessCollection<S>
func lazy<S : CollectionType where S.Index : BidirectionalIndexType>(s: S)
-> LazyBidirectionalCollection<S>
func lazy<S : CollectionType where S.Index : ForwardIndexType>(s: S)
-> LazyForwardCollection<S>
这些方法可以配合像 map
或是 filter
这类接受闭包并进行运行的方法一起,让整个行为变成延时进行的。在某些情况下这么做也对性能会有不小的帮助。例如,直接使用 map
时:
let data = 1...3
let result = data.map {
(i: Int) -> Int in
print("正在处理 \(i)")
return i * 2
}
print("准备访问结果")
for i in result {
print("操作后结果为 \(i)")
}
print("操作完毕")
这么做的输出为:
// 正在处理 1
// 正在处理 2
// 正在处理 3
// 准备访问结果
// 操作后结果为 2
// 操作后结果为 4
// 操作后结果为 6
// 操作完毕
而如果我们先进行一次 lazy
操作的话,我们就能得到延时运行版本的容器:
let data = 1...3
let result = data.lazy.map {
(i: Int) -> Int in
print("正在处理 \(i)")
return i * 2
}
print("准备访问结果")
for i in result {
print("操作后结果为 \(i)")
}
print("操作完毕")
此时的运行结果:
// 准备访问结果
// 正在处理 1
// 操作后结果为 2
// 正在处理 2
// 操作后结果为 4
// 正在处理 3
// 操作后结果为 6
// 操作完毕
对于那些不需要完全运行,可能提前退出的情况,使用 lazy
来进行性能优化效果会非常有效。
【iOS】Swift LAZY 修饰符和 LAZY 方法的更多相关文章
- Swift lazy 修饰符和方法
LAZY 修饰符和 LAZY 方法 由 王巍 (@ONEVCAT) 发布于 2015/10/07 延时加载或者说延时初始化是很常用的优化方法,在构建和生成新的对象的时候,内存分配会在运行时耗费不少时间 ...
- 037——VUE中表单控件处理之表单修饰符:lazy/number/trim
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Vue 修饰符once的方法使用
once:只执行一次 代码: <!doctype html> <html lang="en"> <head> <meta charset= ...
- Vue表单修饰符(lazy,number,trim)
lazy:使用了这个修饰符将会从“input事件”变成change事件进行同步 <div id="example"> <input type="text ...
- iOS Swift结构体与类的方法调度
前言 hello,小伙伴们:在忙碌中闲暇之余给大家聊聊swift的知识点,今天给大家带来的是swift中结构体与类的方法调度详细区别,希望对你有所帮助,好了废话不用多说,接下来步入主题! 1.普通方法 ...
- iOS之属性修饰符 retain、strong和copy区别测试
时不时会有点迷惑属性修饰符retain.strong.copy三者之间的区别,还是把测试过程记录下来好一点! 1.属性修饰符结论 2.给retain.strong.copy修饰的字符串属性赋值指针变化 ...
- final修饰符(5)-final方法
final修饰的类的方法不能被重写,例如如果父类不希望子类重写某个方法,则可以使用final修饰符修饰该方法 在java的Object类里面有一个final方法:getClass(),因为Java不希 ...
- iOS 实例变量修饰符
@public 可以在其他类中访问被@public修饰的成员变量 可以在本类中访问被@public修饰的成员变量 可以在子类中访问fl中被@public修饰的成员变量 @private 不可以在其他类 ...
- ios swift 2 新的OptionSetType使用方法
http://www.rockhoppertech.com/blog/swift-2-optionsettype/?utm_source=tuicool 主要使用方法如下 components([NS ...
随机推荐
- 通过分析HSL/HSB获取图片主色调
这两天稍微研究了一下颜色的HSL/HSB值,主要因为写程序想要实现通过一张图片拿到图片中的最突出的颜色值(类似Groove Music中播放栏背景就是从专辑封面中取出主色调,还有Windows 10任 ...
- Java双等号,Equals(),HashCode()小结
默认情况 - 双等号==,比较的是内存地址. - equals(),默认比较的是内存地址. - hashCode(),默认返回的是object的内存地址. String中方法改写的情况 经常会遇到需要 ...
- [Luogu2991][USACO10OPEN]水滑梯Water Slides
题面戳我 题面描述 受到秘鲁的马丘比丘的新式水上乐园的启发,Farmer John决定也为奶牛们建一个水上乐园.当然,它最大的亮点就是新奇巨大的水上冲浪. 超级轨道包含 E (1 <= E &l ...
- Luogu345: [POI2007]POW-The Flood
题意 见luogu Sol 贪心 从小到大枚举高度,把小于等于这一高度的相邻格子用并查集合并 那么这个集合内的所有格子都一定可以由这个集合内的一个最低点抽完水 那么合并之后(一定要在合并之后) 判断这 ...
- java设计模式-----11、代理模式
Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问. 所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代 ...
- Topshelf 一个简化Windows服务开发的宿主服务框架
Topshelf是 基于.net框架开发的宿主服务框架.该框架简化了服务的创建,开发人员只需要使用 Topshelf编写一个控制台程序,就能安装为Windows服务.之所以这样原因非常简单:调试一个控 ...
- CYQ.data 框架结构
-------------------------V5.0开始(刚开始过滤版本:有些更新功能迁到V4,所以记录在V4那)-----------------------------7:Insert方法增 ...
- Django用户登录与注册系统
一.创建项目 1.1.创建项目和app python manage.py startproject mysite_login python manage.py startapp login 1.2.设 ...
- python—day02
python的版本与基本类型... 第一: 讲了计算机的基础的补充,讲解了什么是操作系统,计算机硬件,应用程序之间的关系: 操作系统是一个能协调管理计算机软件与硬件的软件程序: 能帮我们发送指令集到C ...
- 本站已稳定运行了XX天,网页时间显示功能实现方法
这个是我昨晚上添加的效果, 分为三个部分: 1.本站已稳定运行了多少天的实现: 直接把下面代码复制到后台你想添加的位置即可. 1 2 3 4 5 6 7 8 9 本站已稳定运行了 <strong ...