Swift5.3

作者: 迷路的小小 | 来源:发表于2020-11-23 09:44 被阅读0次

    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-0266Comparable协议
      在枚举也默认实现了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()
    

    在上述代码段中,方法toBoxWrapped需要同是满足协议WhereProElement满足协议BoxPro和协议BoxFloatPro

    9. 简化过渡到简洁的魔术文件字符串SE-0285

    不兼容 swift 5.3 以下

    • 新增#filePath:作用同#file源文件路径
    • 修改#fileModuleName/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 {
        // ...
    }
    

    相关文章

      网友评论

          本文标题:Swift5.3

          本文链接:https://www.haomeiwen.com/subject/ucikiktx.html