[Swift Tips 读书笔记]从 Objective-C 到 Swift(四)

  1. KVO
  1. 局部 scope
  2. 判等
  3. 哈希
  4. 类簇
  5. 调⽤ C 动态库

--

KVO

  • Swift中KVO使用条件 :NSObject 子类、dynamic修饰要观察的属性

     //要观察的类 Car
    class Car: NSObject {  //继承自 NSObject
        dynamic var brand : String?  // dynamic 修饰 brand
    }
    
    //观察者类 Customer
    class Customer: NSObject {
    var car : Car?
    var myContext = 0
    
    override init() {
      super.init()
      car = Car() //实例化一个被观察对象
      car?.brand = "BMW"
      print("现在时间 \(Date()),品牌(\(String(describing: car?.brand))")
      
      // 添加观察者 self 、观察的路径 brand 、观察项 有了新值 、
      car?.addObserver(self, forKeyPath: "brand", options: NSKeyValueObservingOptions.new, context: &myContext)
      
      // 4 秒后给brand赋新值
      DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 4) {
        self.car?.brand = "BYD"
      }
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
          if let change = change ,context == &myContext {
          print("现在时间\(Date()),品牌变化: \(String(describing: change[.newKey]))")
        }
      }
    }
    
    //实例化一个Customer
    _ = Customer()
    
    //log 结果
    现在时间 2017-06-08 02:24:19 +0000,品牌(Optional("BMW")
    现在时间2017-06-08 02:24:23 +0000,品牌变化: Optional(BYD)
    
  • 如果我们想要监测一个类的属性,没有用dynamic修饰。实现的话就是建一个子类,将被观察的属性用 dynamic 重写。

class CarFather: NSObject {
    var brand : String?
}

class Car: CarFather {
dynamic override var brand: String? {
    get { return super.brand }
    set { super.brand = newValue }
  }
}
  • 对于非NSObject的类 ,参考 Observable-Swift

--

局部 scope

    do {
        //局部代码块
    }
    
    //局部代码块
    self.titleLabel = { () -> UILabel in
        let label = UILabel.init(frame: CGRect.init(x: 100, y: 100, width: 80, height: 80))
        label.text = "哈哈哈哈"
        self.view.addSubview(label)
        return label
    }()

--

判等

swift中两个字符串是否相同,使用==判等

OC中==是判断两个对象是否指向同一个内存地址。

swift中==是一个操作符的声明

swift中判断两个引用是否指向同一个内存地址使用===

--

哈希

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表 -------- 摘自百度百科

除⾮我们正在开发⼀个哈希散列的数据结构,否则我们不应该直接依赖系统所实现的哈希值来做其他操作。⾸先哈希的定义是单向的,对于相等的对象或值,我们可以期待它们拥有相同的哈希,但是反过来并不⼀定成⽴。其次,某些对象的哈希值有可能随着系统环境或者时间的变化⽽改变。因此你也不应该依赖于哈希值来构建⼀些需要确定对象唯⼀性的功能,在绝⼤部分情况下,你将会得到错误的结果。

--

类簇

类簇(class cluster)是Cocoa框架中广泛使用的设计模式之一。使用一个统一的公共的类来定制单一的接口。好处是避免公开很多的子类造成混乱。比方说NSNumber,可以通过initWithInt initWithFloat initWithBool生成,实际上它们可能是不同的私有子类对象。

类簇在子类种类繁多,行为相对统一的时候对于简化接口很有帮助。

swift中,初始化的时候我们只能得到当前类的实例,并且要完成所有的配置。就是说,对于一个公共类来说,是不可能在初始化方法中返回其子类的信息。类簇的实现相对于OC来说就麻烦些了,一个有效的方式是通过工厂方法实现类簇。

class Car: NSObject {

var desc: String? {
    return "车的调性"
}
class func descCar(brand: String!) -> Car? {
    var car: Car?
    switch brand {
    case "BMW":
        car = BMW()
    case "BYD":
        car = BYD()
    default:
        car = Car()
    }
    
    return car
  }  
}

class BYD: Car {
override var desc: String? {
    return "Cheap"
  }
}

class BMW: Car {
override var desc: String? {
    return "Sport"
  }
}

--

调⽤ C 动态库

OC是C的超集,但是swift中不能直接使用C的库或者代码,最好的方法是通过{product-modulename}-Bridging-Header.h调用OC,从而调用C。

你可能感兴趣的:([Swift Tips 读书笔记]从 Objective-C 到 Swift(四))