【学习】重学Swift5-错误处理、三方库等

九、其他话题

  1. 错误处理

    enum VendingMachineError: Error {
        case invalidSelection
        case insufficientFunds(coinsNeed: Int)
        case outOfStock
    }
    
    
    struct Item {
        var price: Int
        var count: Int
    }
    
    class VendingMachine {
        var inventory = [
            "Candy Bar": Item.init(price:12, count: 7),
            "Chips": Item.init(price: 20, count: 0),
            "Bread": Item.init(price:15, count:5)
        ]
        
        var coinsDecposited = 0
        
        func vend(itemName: String) throws {
            
            defer {
                print("推出清理")
            }
            print("开始售卖")
            
            guard let item = inventory[itemName] else {
                throw VendingMachineError.invalidSelection
            }
            
            guard item.count > 0 else {
                throw VendingMachineError.outOfStock
            }
            
            guard coinsDecposited >= item.price else {
                throw VendingMachineError.insufficientFunds(coinsNeed: item.price)
            }
            
            coinsDecposited -= item.price
            var newItem = item
            newItem.count -= 1
            inventory[itemName] = newItem
            print("售卖成功")
            
        }
    }
    
    
    var machine = VendingMachine()
    machine.coinsDecposited = 5
    
    do {
        try machine.vend(itemName: "Chips")
    } catch VendingMachineError.invalidSelection {
        print("没有当前商品")
    } catch VendingMachineError.insufficientFunds(let coinsNeeded) {
        print("你需要投\(coinsNeeded)币")
    } catch VendingMachineError.outOfStock {
        print("已售空")
    } catch {
        print("未知错误")
    }
    
    // throw 抛出异常 do-catch处理异常 defer
    
  2. 权限控制

    // open  public internal  fileprivate  private
    /*
    1.类成员的访问级别不能高于类的访问级别;
    2.常量、变量、属性、下标脚本访问级别低于其所声明的类型级别,并且如果不是默认访问级别(internal)要明确声明访问级别。
    3.在不违反1、2的情况下,setter的访问级别可以抵御getter的访问级别。
    4.必要构造方法(required修饰)的访问级别必须和类访问级别相同,狗狗剃的默认逐一构造函数的访问级别不高于其成员的访问级别,其他方法的访问级别遵循规则1
    */
    
  3. 不透明类型

  4. 自动引用计数

    // 循环引用
    // 弱引用weak(对生命周期中引用会变为nil的实例,只能声明变量类型)  无主引用unowned(对初始化赋值之后引用再也不会赋值为nil的实例,无主引用默认始终有值,只能定义为非可选类型) 
    
    // 闭包的循环引用
    lazy var someColisure = {
       [unowned self, weak delegate = self.delegate](index: Int, stringToProgress: String) -> String in
      // code 
    }
    
  5. 内存安全

十、常见三方库

Alamofire  SwiftJSON  R.Swift  MonkeyKing  Kingfisher  SnnapKit  Dollar

十一、加餐

1.可选链、

2.KVC
· 继承自NSObject的类,标记@objc的属性可以使用setValue:(_ forKey:)
· 非继承自NSObject的类和结构体,使用索引+参数值
struct ValueType {
    var name: String
}

var object = ValueType.init(name: "Objective-c")

// set
object[keyPath: \ValueType.name] = "swift"
// get
let valueOfName = object[keyPath: \ValueType.name]
print(valueOfName)

3.KVO
// 只有NSObject才能支持KVO,且要观察的属性必须使用@objc dynamic修饰
// 方法一
class Person: NSObject {
    @objc dynamic var age = 0
}

class ViewController: UIViewController {

    let p = Person()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        p.addObserver(self, forKeyPath: "age", options: [.new, .old], context: nil)
        
        p.age = 33
        // Do any additional setup after loading the view.
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "age" {
            print(change as Any)
        }
    }

}

// 方法二
class Person: NSObject {
    @objc dynamic var age = 0
}

class ViewController: UIViewController {

    @objc dynamic let p = Person()
    
    var ob: NSKeyValueObservation?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.ob = observe(\.p.age, options: [.new, .old], changeHandler: { (_ , change) in
            print(change as Any)
        })
        
        p.age = 33
        // Do any additional setup after loading the view.
    }

}
posted @ 2022-02-26 14:56  weicy  阅读(67)  评论(0编辑  收藏  举报