1. didSet
注释式用法SE-0268
/// `@propertyWrapper`注释属性产生新的`get` 、`set` 方法,
/// 此时不会再产生`oldValue`,
/// 优于直接使用`didSet`
/// 兼容低版本
@propertyWrapper
struct Delayed<Value> {
var wrappedValue: Value {
get {
guard let value = value else {
preconditionFailure("Property \(String(describing: self)) has not been set yet")
}
print("wrappedValue is \(value)")
return value
}
set {
guard value == nil else {
preconditionFailure("Property \(String(describing: self)) has already been set")
}
value = newValue
}
}
var value: Value?
}
class Foo {
@Delayed var bar: Int {
didSet {
/// 这里使用oldValue会直接崩溃
print("didSet called \(bar)")
}
}
}
let foo = Foo()
foo.bar = 1
foo.bar
2. 闭包self
用法SE-0269
优化self
在类等的用法为隐式调用。
- 在类等引用类型中声明
@escaping
的闭包且捕获self
可以省略self
。 - 在结构体等值类型中,可以直接省略
self
。不需要声明闭包为@escaping
逃逸类型,闭包也不需要捕获self
。
/// 1. 解决了循环引用的问题,隐式调用self
/// 2. 兼容低版本
class Cycir {
var name = "xiao bai"
}
class Test {
var cycir = Cycir()
var x = 0
func execute(_ work: @escaping () -> Void) {
work()
}
func method() {
execute { [self] in
x += 1
cycir.name = "xiao hei"
}
}
deinit {
print("Test 释放了")
}
}
var test: Test? = Test()
test?.method()
test?.cycir.name
test = nil
struct TestStr {
var x = 0
func execute(_ work: () -> Void) {
work()
}
mutating func method() {
execute {
x += 1
}
}
}
var testStr: TestStr! = TestStr()
testStr.method()
testStr = nil
3. 异常处理SE-0276
异常处理用法变更,catch
改为只能使用一个
do {
try performTask()
} catch TaskError.someRecoverableError { // OK
recover()
} catch TaskError.someFailure(let msg),
TaskError.anotherFailure(let msg) { // Not currently valid
showMessage(msg)
}
新版更改为
do {
try performTask()
} catch let error as TaskError {
switch error {
case TaskError.someRecoverableError:
recover()
case TaskError.someFailure(let msg),
TaskError.anotherFailure(let msg):
showMessage(msg)
}
}
4. 新增Float16 SE-0276
let float16: Float16 = 3
5. 多尾随闭包 SE-0279 SE-0286
函数末尾多个或单个闭包可以在函数后展开,第一个闭包参数标签可以省略。
UIView.animate(withDuration: 0.3) { [self] in
view.alpha = 0
} completion: { [self] _ in
view.removeFromSuperview()
}
/// equivalent to
UIView.animate(withDuration: 0.3, animations: { [self] in
view.alpha = 0
}, completion: { [self] _ in
view.removeFromSuperview()
})
6. 协议在枚举的用法
-
SE-0280 协议中含有类型为
Self
的静态变量或者返回值为Self
的静态函数可以在枚举中默认实现为同名案例(case
).
protocol DecodingError {
static var fileCorrupted: Self { get }
static func keyNotFound(_ key: String) -> Self
}
enum JSONDecodingError: DecodingError {
case fileCorrupted // error, because it is not a match
case keyNotFound(_ key: String) // error, because it is not a match
}
-
SE-0266
Comparable
协议
在枚举也默认实现了Comparable
协议
enum Membership: Comparable {
case premium
case preferred
case general
}
let cases: [Membership] = [.preferred, .premium, .general]
let sortCase = cases.sorted()
7. String
新增初始化方法 SE-0263
添加可以访问未初始化存储的字符串初始值设定项,iOS14.0以上可以使用。
let myCocoaString = NSString("The quick 我 brown fox jumps over the lazy dog") as CFString
let length = CFStringGetLength(myCocoaString)
let encoing = CFStringBuiltInEncodings.UTF8.rawValue
let capacity = CFStringGetMaximumSizeForEncoding(length, encoing)
let myString = String(unsafeUninitializedCapacity: capacity) { (buffer) -> Int in
var initializedCount = 0
let range = CFRangeMake(0, length)
let _encoding = CFStringBuiltInEncodings.UTF8.rawValue //CFStringGetFastestEncoding(myCocoaString) CFStringEncoding(CFStringEncodings.macChineseSimp.rawValue)
CFStringGetBytes(myCocoaString, range, _encoding, 0, false, buffer.baseAddress, length, &initializedCount)
return initializedCount
}
8. where
SE-0267
关于上下文一般性声明的条款:
protocol WherePro {
associatedtype Element
}
/// 兼容低版本
struct Box<Wrapped> {}
extension Box where Wrapped: WherePro, Wrapped.Element: BoxPro {
func boxes() -> [Box<Wrapped.Element>] {
return [Box<Wrapped.Element>()]
}
func toBox() -> Box<Wrapped.Element> where Wrapped.Element: BoxFloatPro {
return Box<Wrapped.Element>()
}
}
struct C<T>: WherePro {
typealias Element = T
}
protocol BoxPro {}
protocol BoxFloatPro: BoxPro {}
extension String: BoxPro {}
extension Float: BoxFloatPro {}
let c = Box<C<String>>() // [Box<String>]
c.boxes()
let float = Box<C<Float>>()
float.toBox()
float.boxes()
在上述代码段中,方法
toBox
中Wrapped
需要同是满足协议WherePro
、Element
满足协议BoxPro
和协议BoxFloatPro
9. 简化过渡到简洁的魔术文件字符串SE-0285
不兼容 swift 5.3 以下
- 新增
#filePath
:作用同#file
源文件路径 - 修改
#file
为ModuleName/FileName.swift
-
#file
在swift5.3以前#filePath
等同、在未来将于仅仅与#fileID
等同 -
#fileID
在未来的版本可能被替换
#if compiler(>=5.3)
#filePath
#else
#file
#endif
/// 结果相同
-
#fileID
它在所有语言模式下生成新的简明文件字符串,将在swift 6 废弃。
10. @main
基于类型的程序入口点SE-0281
// In a framework:
public protocol ApplicationRoot {
// ...
}
extension ApplicationRoot {
public static func main() {
// ...
}
}
// In MyProgram.swift:
@main
struct MyProgram: ApplicationRoot {
// ...
}
网友评论