亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在iOS中實現多繼承與多重代理

發布時間:2021-06-11 16:59:24 來源:億速云 閱讀:342 作者:Leah 欄目:移動開發

本篇文章給大家分享的是有關怎么在iOS中實現多繼承與多重代理,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

1. 多繼承

1. 實現過程

swift中的類可以遵守多個協議,但是只可以繼承一個類,而值類型(結構體和枚舉)只能遵守單個或多個協議,不能做繼承操作.

多繼承的實現:協議的方法可以在該協議的extension中實現

protocol Behavior {
 func run()
}
extension Behavior {
 func run() {
  print("Running...")
 }
}

struct Dog: Behavior {}

let myDog = Dog()
myDog.run() // Running...

無論是結構體還是類還是枚舉都可以遵守多個協議,所以要實現多繼承,無非就是多遵守幾個協議的問題.

下面舉個例子.

2. 通過多繼承為UIView擴展方法

// MARK: - 閃爍功能
protocol Blinkable {
 func blink()
}
extension Blinkable where Self: UIView {
 func blink() {
  alpha = 1
  
  UIView.animate(
   withDuration: 0.5,
   delay: 0.25,
   options: [.repeat, .autoreverse],
   animations: {
    self.alpha = 0
  })
 }
}

// MARK: - 放大和縮小
protocol Scalable {
 func scale()
}
extension Scalable where Self: UIView {
 func scale() {
  transform = .identity
  
  UIView.animate(
   withDuration: 0.5,
   delay: 0.25,
   options: [.repeat, .autoreverse],
   animations: {
    self.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
  })
 }
}

// MARK: - 添加圓角
protocol CornersRoundable {
 func roundCorners()
}
extension CornersRoundable where Self: UIView {
 func roundCorners() {
  layer.cornerRadius = bounds.width * 0.1
  layer.masksToBounds = true
 }
}

extension UIView: Scalable, Blinkable, CornersRoundable {}

 cyanView.blink()
 cyanView.scale()
 cyanView.roundCorners()

怎么在iOS中實現多繼承與多重代理

這樣,如果我們自定義了其他View,只需要放大和縮小效果,遵守Scalable協議就可以啦!

3. 多繼承鉆石問題(Diamond Problem),及解決辦法

請看下面代碼

protocol ProtocolA {
  func method()
}

extension ProtocolA {
  func method() {
    print("Method from ProtocolA")
  }
}

protocol ProtocolB {
  func method()
}

extension ProtocolB {
  func method() {
    print("Method from ProtocolB")
  }
}

class MyClass: ProtocolA, ProtocolB {}

此時ProtocolA和ProtocolB都有一個默認的實現方法method(),由于編譯器不知道繼承過來的method()方法是哪個,就會報錯.

?鉆石問題Diamond Problem,當某一個類或值類型在繼承圖譜中有多條路徑時就會發生.

解決方法:

1. 在目標值類型或類中重寫那個發生沖突的方法method().

2. 直接修改協議中重復的方法.

文章開頭我們提到的問題2,我們可以試著用多重代理去解決這個問題.

2. 多重代理

1. 多重代理的實現過程

我們以一個代理的經典問題來表述:

主人叫寵物們去吃飯,吃這個動作作為一個協議,我們要做到統一管理.

1. 定義協議

protocol MasterOrderDelegate: class {
  func toEat(_ food: String)
}

2. 定義一個類: 用來管理遵守協議的類

這邊用了NSHashTable來存儲遵守協議的類,NSHashTable和NSSet類似,但又有所不同,總的來說有這幾個特點:

1. NSHashTable中的元素可以通過Hashable協議來判斷是否相等.

2. NSHashTable中的元素如果是弱引用,對象銷毀后會被移除,可以避免循環引用.

class masterOrderDelegateManager : MasterOrderDelegate {
  private let multiDelegate: NSHashTable<AnyObject> = NSHashTable.weakObjects()

  init(_ delegates: [MasterOrderDelegate]) {
    delegates.forEach(multiDelegate.add)
  }
  
  // 協議中的方法,可以有多個
  func toEat(_ food: String) {
    invoke { $0.toEat(food) }
  }
  
  // 添加遵守協議的類
  func add(_ delegate: MasterOrderDelegate) {
    multiDelegate.add(delegate)
  }
  
  // 刪除指定遵守協議的類
  func remove(_ delegateToRemove: MasterOrderDelegate) {
    invoke {
      if $0 === delegateToRemove as AnyObject {
        multiDelegate.remove($0)
      }
    }
  }
  
  // 刪除所有遵守協議的類
  func removeAll() {
    multiDelegate.removeAllObjects()
  }

  // 遍歷所有遵守協議的類
  private func invoke(_ invocation: (MasterOrderDelegate) -> Void) {
    for delegate in multiDelegate.allObjects.reversed() {
      invocation(delegate as! MasterOrderDelegate)
    }
  }
}

3. 其余部分

class Master {
  weak var delegate: MasterOrderDelegate?
  func orderToEat() {
    delegate?.toEat("meat")
  }
}

class Dog {}
extension Dog: MasterOrderDelegate {
  func toEat(_ food: String) {
    print("\(type(of: self)) is eating \(food)")
  }
}

class Cat {}
extension Cat: MasterOrderDelegate {
  func toEat(_ food: String) {
    print("\(type(of: self)) is eating \(food)")
  }
}

let cat = Cat()
let dog = Dog()
let cat1 = Cat()

let master = Master()
// master的delegate是弱引用,所以不能直接賦值
let delegate = masterOrderDelegateManager([cat, dog])
// 添加遵守該協議的類
delegate.add(cat1)
// 刪除遵守該協議的類
delegate.remove(dog)

master.delegate = delegate
master.orderToEat()

// 輸出
// Cat is eating meat
// Cat is eating meat

以上就是怎么在iOS中實現多繼承與多重代理,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

ios
AI

南康市| 嫩江县| 原阳县| 双鸭山市| 道孚县| 象州县| 铁力市| 黔西| 晴隆县| 娄底市| 宁海县| 延长县| 宜昌市| 奎屯市| 龙泉市| 九寨沟县| 平度市| 和硕县| 吉林市| 长汀县| 丰都县| 小金县| 平安县| 南华县| 潞西市| 怀化市| 聊城市| 通化市| 新平| 马尔康县| 巴东县| 余姚市| 丹凤县| 台山市| 永和县| 巴塘县| 黄山市| 岢岚县| 中江县| 新巴尔虎右旗| 垦利县|