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 方法上。

计算属性本质上是一种方法,可以通过 getset 来访问和修改值。如果你想在 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 发现报错了:

这有点反直觉,因为在整个 userNamegetset 过程中,都没有修改其本身或者属性,但很明显编译器并不能进一步分析你的底层代码,而是简单粗暴的认为,只要有 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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
CareyWYR7 小时前
我开发了一款工具箱类型APP:CreativeUtil
ios·app·mac
2501_915918419 小时前
只有 Flutter IPA 文件,通过多工具组合完成有效混淆与保护
android·flutter·ios·小程序·uni-app·iphone·webview
程序员老刘11 小时前
重拾Eval能力:D4rt为Flutter注入AI进化基因
flutter·客户端·dart
得物技术15 小时前
得物App智能巡检技术的探索与实践
app·客户端
川石课堂软件测试15 小时前
Android和iOS APP平台测试的区别
android·数据库·ios·oracle·单元测试·测试用例·cocoa
liusheng15 小时前
Capacitor + React 的 iOS 侧滑返回手势
前端·ios
大熊猫侯佩15 小时前
Swift 6.2 列传(第十七篇):钟灵的“雷电蟒”与测试附件
单元测试·swift·apple
2501_9159184116 小时前
除了 Perfdog,如何在 Windows 环境中完成 iOS App 的性能测试工作
android·ios·小程序·https·uni-app·iphone·webview
七月巫山晴17 小时前
【iOS】NSString&NSRange&NSCharacterSet
ios·cocoa·iphone
h-189-53-67120717 小时前
2026(原创)Guideline 4.3(a) - Design - Spam苹果上架iOS审核被拒AppStore卡审解决办法思路
ios