怎么在iOS中實(shí)現(xiàn)多繼承與多重代理-創(chuàng)新互聯(lián)

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

成都創(chuàng)新互聯(lián)網(wǎng)絡(luò)公司擁有十載的成都網(wǎng)站開發(fā)建設(shè)經(jīng)驗(yàn),近1000家客戶的共同信賴。提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)站開發(fā)、網(wǎng)站定制、賣友情鏈接、建網(wǎng)站、網(wǎng)站搭建、自適應(yīng)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)師打造企業(yè)風(fēng)格,提供周到的售前咨詢和貼心的售后服務(wù)

1. 多繼承

1. 實(shí)現(xiàn)過程

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

多繼承的實(shí)現(xiàn):協(xié)議的方法可以在該協(xié)議的extension中實(shí)現(xiàn)

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

struct Dog: Behavior {}

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

無論是結(jié)構(gòu)體還是類還是枚舉都可以遵守多個(gè)協(xié)議,所以要實(shí)現(xiàn)多繼承,無非就是多遵守幾個(gè)協(xié)議的問題.

下面舉個(gè)例子.

2. 通過多繼承為UIView擴(kuò)展方法

// 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中實(shí)現(xiàn)多繼承與多重代理

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

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

請(qǐng)看下面代碼

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 {}

此時(shí)ProtocolA和ProtocolB都有一個(gè)默認(rèn)的實(shí)現(xiàn)方法method(),由于編譯器不知道繼承過來的method()方法是哪個(gè),就會(huì)報(bào)錯(cuò).

?鉆石問題Diamond Problem,當(dāng)某一個(gè)類或值類型在繼承圖譜中有多條路徑時(shí)就會(huì)發(fā)生.

解決方法:

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

2. 直接修改協(xié)議中重復(fù)的方法.

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

2. 多重代理

1. 多重代理的實(shí)現(xiàn)過程

我們以一個(gè)代理的經(jīng)典問題來表述:

主人叫寵物們?nèi)コ燥?吃這個(gè)動(dòng)作作為一個(gè)協(xié)議,我們要做到統(tǒng)一管理.

1. 定義協(xié)議

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

2. 定義一個(gè)類: 用來管理遵守協(xié)議的類

這邊用了NSHashTable來存儲(chǔ)遵守協(xié)議的類,NSHashTable和NSSet類似,但又有所不同,總的來說有這幾個(gè)特點(diǎn):

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

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

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

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

  // 遍歷所有遵守協(xié)議的類
  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])
// 添加遵守該協(xié)議的類
delegate.add(cat1)
// 刪除遵守該協(xié)議的類
delegate.remove(dog)

master.delegate = delegate
master.orderToEat()

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

以上就是怎么在iOS中實(shí)現(xiàn)多繼承與多重代理,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站muchs.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)頁名稱:怎么在iOS中實(shí)現(xiàn)多繼承與多重代理-創(chuàng)新互聯(lián)
本文網(wǎng)址:http://muchs.cn/article18/iocgp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、定制網(wǎng)站、ChatGPT、網(wǎng)站維護(hù)、微信小程序小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)