[译] 在 iOS Swift 中的懒加载变量

简介: 这篇文章解释了在 Swift 中懒加载变量是如何工作的,你必须对闭包有一些了解。

原文地址:lazy var in ios swift
原文作者:Abhimuralidharan
译文出自:掘金翻译计划
本文永久链接:github.com/xitu/gold-m…
译者:kirinzer
校对者:portandbridge, iWeslie


这篇文章解释了在 Swift 中懒加载变量是如何工作的,你必须对闭包有一些了解。

阅读这篇文章获取更多关于闭包的信息.

当我们进行 iOS 开发时,我们应该非常关注应用程序的内存占用情况。如果应用程序很复杂,那么内存问题就会是对于开发者的一个主要的挑战。所以,首先考虑到内存分配问题的开发者能够真正的写出优化的代码。除非确实有必要,否则开发者要避免做一些耗时的工作。那些复杂的分配内存操作会消耗更多的时间,并且对于程序的性能有严重的影响。
image.png

Swift 有内置在语言中的机制,可以即时的计算那些耗时工作。它叫做懒加载变量。这种变量只有在你第一次需要它的时候才被指定的方法创建。如果从没有使用过该变量。那么方法就不会运行,所以它可以帮助减少一些处理时间。

苹果的官方文档写道:

一个懒加载储存属性是种只有在首次使用时,才计算其初始值的属性。你可以通过在声明前加 lazy 修饰符来标示一个懒加载存储属性。

你必须将一个懒加载属性声明为一个变量(通过 var 关键字),因为它的初始化值也许不能获得,直到实例的初始化完成。常量属性在初始化完成之前一定会有一个值,因此不能用懒加载声明。

为了解释这些,我会使用一个很基础的示例:假设有一个结构体叫做 InterviewCandidate。它有一个可选的布尔值,决定候选人正在申请 iOS 或者 Android。iOSResumeDescription 和 androidResumeDescription 被声明为懒加载属性。那么在下面的代码中,一个人是 iOS 开发者,懒加载变量 iOSResumeDescription 将会在调用打印方法的时候被初始化。没有被调用的 androidResumeDescription 就会是 nil。

//: Playground - noun: 人们用来玩耍的地方
import UIKit


struct InterviewCandidate {
    var isiOS:Bool?
    
    lazy var iOSResumeDescription: String = {
        return "I am an iOS developer"
    }()
    lazy var androidResumeDescription: String = {
        return "I am an android developer"
    }()
}

var person1 = InterviewCandidate()
person1.isiOS = true

if person1.isiOS! {
    print(person1.iOSResumeDescription)
} else {
    print(person1.androidResumeDescription)

}

这是一个非常基础的例子。如果我们有一个复杂的类或结构,它包含从循环的函数返回结果的计算变量,并且如果我们创建 1000 个这样的对象,那么性能和内存将会受到影响。

懒加载存储属性 vs 存储属性

这有一些懒加载属性相对于存储属性的优点。

  1. 只有在读取懒加载属性时,才会执行与该属性关联的闭包。 因此,如果由于某种原因该属性未被使用(可能是因为用户的某些决定),则可以避免不必要的分配和计算。
  2. 你可以使用一个存储属性给懒加载属性赋值。
  3. 注意 你能够在懒加载的属性闭包内部使用 self。这不会导致任何循环引用。原因在于它立即使用的这个闭包 {}() 被认为是 @noescape。它不会引用捕获的 self。

但是,如果你在 方法 中使用 self。事实上,如果你正在使用的是一个类而不是结构体,你也应该在你的方法内声明 [unowned self] 那样你才不会创建一个强引用(查看下面的代码)。

// playground code

import UIKit
import Foundation

class InterviewTest {
    var name: String
    lazy var greeting : String = { return “Hello \(self.name)” }()
    // 这里没有循环引用 ..

    init(name: String) {
        self.name = name
    }
}

let testObj = InterviewTest(name:”abhi”)

testObj.greeting

你能够引用这个变量,无论你是否使用了闭包。

lazy var iOSResumeDescription = “I am an iOS developer”

这样的语法也可以运行。

注意:记住,懒加载属性的用途是只有它们第一次被需要的时候才会被计算,在这之后它们的值就被存储下来了。所以,如果你第二次使用 iOSResumeDescription,预先存储的属性就会返回。

懒加载规则:

  • 你不能对 let 类型使用 lazy。
  • 你不能对于 计算属性 使用它。因为一个计算属性会在每次我们试图访问它的时候去执行在计算代码块中的代码并返回相应的值。
  • 你只能对 struct 和 class 的成员使用 lazy。
  • 懒加载变量不是原子初始化类型,所以它并不是线程安全的。
目录
相关文章
|
1月前
|
Swift iOS开发
iOS Swift使用Alamofire请求本地服务器报错-1002
iOS Swift使用Alamofire请求本地服务器报错-1002
52 1
|
2月前
|
Unix 调度 Swift
苹果iOS新手开发之Swift 中获取时间戳有哪些方式?
在Swift中获取时间戳有四种常见方式:1) 使用`Date`对象获取秒级或毫秒级时间戳;2) 通过`CFAbsoluteTimeGetCurrent`获取Core Foundation的秒数,需转换为Unix时间戳;3) 使用`DispatchTime.now()`获取纳秒级精度的调度时间点;4) `ProcessInfo`提供设备启动后的秒数,不表示绝对时间。不同方法适用于不同的精度和场景需求。
48 3
|
6天前
|
安全 编译器 Swift
探索iOS开发之旅:Swift编程语言的魅力与挑战
【9月更文挑战第5天】在iOS应用开发的广阔天地中,Swift作为苹果官方推荐的编程语言,以其简洁、高效和安全的特点,成为了开发者的新宠。本文将带领你领略Swift语言的独特魅力,同时探讨在实际开发过程中可能遇到的挑战,以及如何克服这些挑战,成为一名优秀的iOS开发者。
|
6天前
|
设计模式 前端开发 Swift
探索iOS开发:Swift与Objective-C的较量
在这篇文章中,我们将深入探讨iOS开发的两大编程语言——Swift与Objective-C。我们将分析这两种语言的特性、优势和局限性,并讨论它们在现代iOS开发中的应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和建议。
20 3
|
1月前
|
存储 移动开发 Swift
使用Swift进行iOS应用开发:探索现代移动开发的魅力
【8月更文挑战第12天】使用Swift进行iOS应用开发,不仅能够享受到Swift语言带来的简洁、快速、安全的编程体验,还能够充分利用iOS平台提供的丰富资源和强大功能。然而,iOS应用开发并非易事,需要开发者具备扎实的编程基础、丰富的实践经验和不断学习的精神。希望本文能够为您的iOS应用开发之旅提供一些有益的参考和帮助。
|
12天前
|
测试技术 Swift iOS开发
探索iOS自动化测试:使用Swift编写UI测试
【8月更文挑战第31天】在软件开发的海洋中,自动化测试是保证船只不偏离航线的灯塔。本文将带领读者启航,深入探索iOS应用的自动化UI测试。我们将通过Swift语言,点亮代码的灯塔,照亮测试的道路。文章不仅会展示如何搭建测试环境,还会提供实用的代码示例,让理论知识在实践中生根发芽。无论你是新手还是有经验的开发者,这篇文章都将是你技能提升之旅的宝贵指南。
|
12天前
|
移动开发 安全 Swift
探索iOS开发:从零开始的Swift之旅
【8月更文挑战第31天】本文将带你开启一段Swift编程语言的奇幻旅程,通过简单易懂的方式介绍Swift的基本概念和编程实践。我们将一起构建一个简单的iOS应用,体验从代码到界面的转变。无论你是编程新手还是希望扩展技能的开发者,这篇文章都会为你提供宝贵的知识和启发。
|
1月前
|
API Swift C语言
探索iOS开发:Swift中的异步编程与GCD应用
【8月更文挑战第4天】在iOS开发的海洋中,掌握Swift语言的航向是至关重要的。本文将引领你深入理解Swift中的异步编程概念,并借助Grand Central Dispatch(GCD)这一强大的工具,来简化并发编程的复杂性。我们将通过实际代码示例,展现如何在iOS应用中高效地管理后台任务和提升用户界面的响应性。
42 3
|
2月前
|
Swift iOS开发 Kotlin
苹果iOS新手开发之Swift中实现类似Kotlin的作用域函数
Swift可通过扩展实现类似Kotlin作用域函数效果。如自定义`let`, `run`, `with`, `apply`, `also`,增强代码可读性和简洁性。虽无直接内置支持,但利用Swift特性可达成相似功能。
48 7
|
2月前
|
调度 Swift Android开发
苹果iOS新手开发之Swift中的并发任务和消息机制
Swift的消息机制类似Android的Handler,实现任务调度有三种方式: 1. **Grand Central Dispatch (GCD)**:使用`DispatchQueue`在主线程或后台线程执行任务。 2. **OperationQueue**:提供高级接口管理`Operation`对象。 3. **RunLoop**:处理事件如输入源、计时器,类似Android的`Looper`和`Handler`。 **示例**: - GCD:在不同线程执行代码块。 - OperationQueue:创建操作并执行。 - RunLoop:用Timer添加到RunLoop中。
71 2