Swift 5.9 新特性:consume

前言

在 Swift 中,是使用引用计数和 copy-on-wirte 的机制来管理内存,通常情况下,开发者只管使用即可,不用太关心内存相关。但对于一些性能敏感的代码来说,开发者可能会希望在语言层面上能够控制减少 retain、release 的调用。比如下面的代码:

swift 复制代码
func test() {
  var x: [Int] = [1, 3, 4]
  doStuffUniquely(with: x)
  x = []
}

func doStuffUniquely(with value: [Int]) {
  var newValue = value
  newValue.append(42)
  print(newValue)
}

上述代码中,变量 x 存储的是一个整型的数组。然后将其当做参数传递给了 doStuffUniquely(),接着在 doStuffUniquely() 函数体内部对 value 进行了数据处理。最后,x 被清空。

再将 x 传递给 doStuffUniquely() 的时候应该存在一种机制将 x 的数据所有权也转交过去。因为在 test() 中的后续代码中也并没有对 x 的数据进行使用。

现有的代码会存在一定的性能浪费,因为在 doStuffUniquely() 中的 var newValue = value 执行时会进行数组内容的 copy-on-wirte,而且当 doStuffUniquely() 函数执行完之后, newValue 因为作用域的原因而被释放,从而再将新开辟存储数组元素的空间清空。

基于以上的原因,Swift 5.9 推出了 consume 关键字,使用该关键字可以避免上述代码的性能损耗。

consume 的使用

对于上述代码,修改 doStuffUniquely() 函数调用这一行即可:

scss 复制代码
doStuffUniquely(with: consume x)

在传递的参数前面添加一个 consume 关键字修饰,这样就等于告诉编译器,x 变量存储的数据所有权,请转交给 doStuffUniquely() 函数的参数。需要注意的是,如果这样写之后,我们在 test() 函数中的后续代码就不可以再对 x 的数据进行修改了,因为我们已经明确的将 x 的数据所有权已经交了出去。

如果,后续再对 x 进行修改的话编译器会报错:

与 let 搭配使用

对于常量来说,也可以通过使用 consume 来进行生命周期的终结。当常量使用 consume 之后,常量就不可用了,因为它的值所有权已被交出,且它不可重新被赋值。

需要说明的是, consume 是对绑定的操作,而不是对值进行操作,所以如果将 x 赋值给另一个常量 other,当 x consume 之后,x 已不能使用,而 other 是不受影响的:

scss 复制代码
func useX(_ x: Int) -> () {}

func f() {
  let x = 10
  useX(x)
  let other = x
  _ = consume x
  useX(other)
}

_ = consume x 执行完之后, x 的生命周期已结束。而 other 是可以正常使用的,所以 useX(other) 并没有什么问题。

与 var 搭配使用

与 var 搭配使用则与 let 使用略有不同,当 consume 修饰的变量重新赋值之后,是可以正常使用的:

ini 复制代码
struct User {
    var name: String
}
    
func test() {
    var user = User(name: "jack")
    _ = consume user
    
//  user.name = "" // 编译报错
    user = User(name: "rose")
    print(user.name)
}

上面的代码我们可以看到,如果在 user consume 之后,直接对 user 进行 name 的赋值是不行的,原因就是 user 的数据所有权已经没了。

而对 user 进行重新赋值则是没问题的,后续也可以正常使用。

相关推荐
初级代码游戏2 天前
iOS开发 SwiftUI 14:ScrollView 滚动视图
ios·swiftui·swift
初级代码游戏2 天前
iOS开发 SwitftUI 13:提示、弹窗、上下文菜单
ios·swiftui·swift·弹窗·消息框
zhyongrui2 天前
托盘删除手势与引导体验修复:滚动冲突、画布消失动画、气泡边框
ios·性能优化·swiftui·swift
zhangfeng11333 天前
CSDN星图 支持大模型微调 trl axolotl Unsloth 趋动云 LLaMA-Factory Unsloth ms-swift 模型训练
服务器·人工智能·swift
zhyongrui3 天前
SnipTrip 发热优化实战:从 60Hz 到 30Hz 的性能之旅
ios·swiftui·swift
大熊猫侯佩4 天前
Neo-Cupertino 档案:撕开 Actor 的伪装,回归 Non-Sendable 的暴力美学
swift·observable·actor·concurrency·sendable·nonsendable·data race
2501_915921436 天前
在没有源码的前提下,怎么对 Swift 做混淆,IPA 混淆
android·开发语言·ios·小程序·uni-app·iphone·swift
00后程序员张6 天前
对比 Ipa Guard 与 Swift Shield 在 iOS 应用安全处理中的使用差异
android·开发语言·ios·小程序·uni-app·iphone·swift
大熊猫侯佩6 天前
星际穿越:SwiftUI 如何让 ForEach 遍历异构数据(Heterogeneous)集合
swiftui·swift·遍历·foreach·any·异构集合·heterogeneous
hjs_deeplearning7 天前
认知篇#15:ms-swift微调中gradient_accumulation_steps和warmup_ratio等参数的意义与设置
开发语言·人工智能·机器学习·swift·vlm