iOS:Non-mutating 关键字介绍

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

上次的文章中,我们讲到了 mutating 这个关键字,当时提到的所有示例都是关于在方法中修改属性的,但 Swift 还提供了一种将某些上下文标记为非可变的方法。

mutating 的使用和实现原理

这个关键字是 nonmutating,用于标记值类型(枚举、结构体)中的方法。虽然实际的应用场景非常少,但在某些情况下它仍然是一个有用的功能。

nonmutating 的使用方法

nonmutating 关键字也是直接标记在方法名前面的,用来向编译器保证,在这个方法中并不会改变任何自身的属性:

swift 复制代码
struct Point {
    var x = 0.0, y = 0.0
    
    nonmutating func description() -> String {
        return "(\(x), \(y))"
    }
}

nonmutating 关键字标记在 description 方法上,表明我们不会在 description 方法里对自身做出修改,不过......好像没什么用对吧?因为就算不加 nonmutating 关键字,程序一样会正常运行。

实际的应用场景

其实 nonmutating 关键字更多被用在计算属性(computed properties)的 set 方法上。

计算属性本质上是一种方法,可以通过 get 和 set 来访问和修改值。如果你想在 set 方法中改变其他属性而不改变该属性本身,你就可以使用 nonmutating set。

举个例子,假如我们有一个存储工具类叫 Storage,里面有个计算属性叫 userName,当获取 userName 时,从 UserDefault 中获取(get 方法),当设置 userName 时,把新值存储到 UserDefault 中(set 方法)。

csharp 复制代码
struct Storage {
    private let userNameKey = "userNameKey"

    var userName: String? {
        get {
            return UserDefaults.standard.string(forKey: userNameKey)
        }
        set {
            UserDefaults.standard.set(newValue, forKey: userNameKey)
        }
    }
}

当我们用 let 创建一个 Storage 时,设置 userName 发现报错了:

这有点反直觉,因为在整个 userName 的 get 和 set 过程中,都没有修改其本身或者属性,但很明显编译器并不能进一步分析你的底层代码,而是简单粗暴的认为,只要有 set 方法,就以为你要做修改,因此报错。

想要修复这个报错,就需要用 nonmutating 关键字了,只需要在 set 方法前加上这个关键字,就可以正常运行了。

c 复制代码
struct Storage {
...
        nonmutating  set {
            UserDefaults.standard.set(newValue, forKey: userNameKey)
        }
...
}

另外,在协议中也可以使用这个关键字:

swift 复制代码
protocol Storage {
    var userName: String? { get nonmutating set }
}

总结

通过这个关键字可以显式告诉编译器该方法/访问器不会改变其值,同时也为了代码的安全,编译器不会让你从 nonmutating 的方法中访问该类型的任何可变成员。

希望通过本文能让你深入了解 nonmutating 关键字的用法和作用,虽然在实际开发过程中大概用不上,但知道一下总是好的。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
Geek-Chow18 小时前
00 Apple Code Signing, In Depth — A Series
ios
传奇开心果编程1 天前
【Flutter踩坑排雷】第25课:ScrollController 误用坑|跳转失效、监听泄漏与“控制器未附加”
android·flutter·ios·移动开发·跨平台·dart·声明式ui
90后的晨仔1 天前
macOS 27 下两个 Xcode 坑:真机 DDI 错配与模拟器 App Translocation
ios
开心猴爷1 天前
iOS 上架 App 流程
后端·ios
奶油话梅糖1 天前
用 iPhone 扫一间房,AI 帮你在浏览器里 1:1 重建它:Wes Bos 的 scan-to-threejs 工作流
人工智能·ios·iphone
程序员老刘1 天前
Flutter 3.50更新,开发者应该关注什么?
flutter·ai编程·客户端
布莱克6052 天前
Swift 常量详解:从 let 到编译期优化
服务器·开发语言·ssh·swift·常量·let
布莱克6052 天前
Swift 可选类型(Optionals)详解:从原理到实战
开发语言·安全·ssh·swift·optional·可选类型
茶底世界之下2 天前
阴天窗边的柿子:用 Awaking 让暖色成为主角
ios·app·产品
kango2 天前
iOS 远程推送全链路拆解:从 deviceToken 到多账号绑定
ios·app