Swift 5.8 新特性

2023-03-30 20:24:02 浏览数 (1)

Swift 5.8 内置于 Xcode 14.3,增加了如下的几个重要的新特性。

功能返回部署

  • 增加了@backDeployed(before: ...)属性,允许将修饰的功能扩展到没有将其作为应用程序二进制接口(ABI)的旧操作系统中,即在旧版本上使用新 API。
代码语言:javascript复制
@backDeployed(before: iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4)
  • @backDeployed要求当前所在类型与修饰内容的访问权限不低于public
  • @backDeployed适用于计算属性与方法。
代码语言:javascript复制
public struct Person {
    @available(iOS 11, *)
    @backDeployed(before: iOS 16.4)
    public var age: Int {
        return Int.random(in: 0 ... 100)
    }

    @available(iOS 13.0, *)
    @backDeployed(before: iOS 16.4)
    public func info() {}
}

[weak self]改变

Swift 5.3 之后 self 可以在闭包中有条件省略,Swift 5.8 之后类中的[weak self]也可以省略 self。

代码语言:javascript复制
import UIKit

class ViewController: UIViewController {
    var count = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        let action = UIAction(title: "计数") { [weak self] _ in
            guard let self = self else { return }
            // Swift 5.8之前
            // self.count  = 1
            // print(self.count)

            // Swift 5.8之后
            count  = 1
            print(count)
        }

        let navItem = UIBarButtonItem(systemItem: .done, primaryAction: action)
        navigationItem.leftBarButtonItem = navItem
    }
}

取消result builders中对变量的使用限制

Swift 5.4 中引入的 result builders 对局部变量有一些限制:不能使用lazy、不能被计算、不能有观察器、不能附加属性包装等。Swift 5.8 之后解除了所有使用限制。

代码语言:javascript复制
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            lazy var name = "zhangsan"

            var age: Int {
                return 10
            }

            var sex: String = "male" {
                willSet {
                    print(newValue)
                }

                didSet {
                    print(oldValue)
                }
            }

            Text("Hello, (name), (age), (sex)")

            Button("change") {
                sex = "female"
            }
        }
        .padding()
    }
}

支持集合类型向下类型转换

Swift 5.8 之前集合类型不支持直接向下类型转换,需要使用if let as?。Swift 5.8 之后语法上支持直接向下类型转换,但也仅仅是语法不再报错,并不能保证转换成功。

代码语言:javascript复制
class Vehicle {
    var name: String

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

class Bicycle: Vehicle {
    func run() {
        print("Bicycle (name) Run run")
    }
}

func test(vehicles: [Vehicle]) {
    // Swift 5.8之前
    if let bicycles = vehicles as? [Bicycle] {
        for bicycle in bicycles {
            bicycle.run()
        }
    } else {
        print("error")
    }

    // Swift 5.8之后
    switch vehicles {
    case let bicycles as [Bicycle]:
        for bicycle in bicycles {
            bicycle.run()
        }
    default:
        print("default")
    }
}

#file与#filepath

#file的输出不再包含文件的完整路径,只包含模块与文件名,如果需要显示完整路径使用新的编译符号#filepath

代码语言:javascript复制
func test() {
    print(#file)
    print(#filepath)
}

test()

0 人点赞