最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解iOS中跨頁面狀態(tài)同步方案比較

 更新時(shí)間:2019年09月24日 09:58:11   作者:Tpphha  
這篇文章主要介紹了詳解iOS中跨頁面狀態(tài)同步方案比較,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

由于團(tuán)隊(duì)希望項(xiàng)目能夠去 CoreData 化,而以往狀態(tài)同步都是依賴于 CoreData 的NSFetchedResultsController。因此去 CoreData 則必須尋找一種替代方案來進(jìn)行狀態(tài)同步。

NotificationCenter

狀態(tài)同步實(shí)際是一對(duì)多的場景,也就是一個(gè)事件可以被多個(gè)觀察者監(jiān)聽到。而蘋果的系統(tǒng)框架自帶的 NotificationCenter 正是用來適配這種場景,并且其也是被系統(tǒng)框架本身及我們開發(fā)者大面積使用的。用法如下:

  1. 定義通知名字,以及需要額外傳遞信息的 key
  2. 基于 target-action 的方式注冊(cè)通知
open func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)

實(shí)現(xiàn)監(jiān)聽通知的方法

func onReceivedNotification(note: NSNotification)

發(fā)送通知,可以傳遞發(fā)送通知的對(duì)象(object)以及一些額外的信息(userInfo)

open func post(name aName: NSNotification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable : Any]? = nil)

移除注冊(cè)的通知

open func removeObserver(_ observer: Any, name aName: NSNotification.Name?, object anObject: Any?)

當(dāng)然 NotificationCenter 也提供了一種更加便利基于 block 的方式注冊(cè)監(jiān)聽通知,其將 2,3 兩個(gè)步驟整合為 1 個(gè)步驟。

open func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol

整體流程很清晰,簡單易用,但是卻有一個(gè)嚴(yán)重的缺點(diǎn) —— 弱類型。我們接收到的是一個(gè)NSNotification對(duì)象。

open class NSNotification : NSObject, NSCopying, NSCoding {
  open var name: NSNotification.Name { get }
  open var object: Any? { get }
  open var userInfo: [AnyHashable : Any]? { get }
}

假設(shè)我們需要傳遞一個(gè)關(guān)注狀態(tài)改變的信息,那么需要包含關(guān)注更改后的狀態(tài)以及被關(guān)注者的 ID。那么我們需要從 userInfo 中取出所需要的值:

let following = notification.userInfo["FollowingKey"] as! NSNumber
let userID = notification.userInfo["UserIDKey"] as! NSNumber;

也就是說接收通知的一方一般需要要查看文檔才知道怎樣從 userInfo 取值,取的值的類型又是什么。這對(duì)于使用是極為不方便的。

SwiftNotificationCenter

SwiftNotificationCenter是一種面向協(xié)議的通知中心方案。使用方式如下:

定義協(xié)議

protocol FollowingChanged {
  func followingDidChange(following: Bool, userID: NSNumber)
}

基于協(xié)議注冊(cè)通知

Broadcaster.register(Update.self, observer: observer)

實(shí)現(xiàn)協(xié)議方法

extension ViewController: FollowingChanged {
 func followingDidChange(following: Bool, userID: NSNumber) {
  // do something
 }
}

發(fā)送通知

Broadcaster.notify(FollowingChanged.self) {
  $0.followingDidChange(following, userID)
}

移除注冊(cè)的通知

Broadcaster.unregister(Update.self, observer: observer)

我們可以看到,其基于協(xié)議的方式解決了弱類型的問題,并且其通過AssociatedObject實(shí)現(xiàn)了通知的自動(dòng)移除。但其也存在著擴(kuò)展性較差的問題。

依然是關(guān)注改變的場景,假如隨著業(yè)務(wù)的發(fā)展,有的地方需要知道關(guān)注后是否為互關(guān)的狀態(tài),那么又需要增加一個(gè)字段來標(biāo)識(shí)。因此我們需要修改協(xié)議,增加參數(shù),且由于其不是必須傳遞的參數(shù),因此是 optional 類型。

protocol FollowingChanging {
  func followingDidChange(following: Bool, userID: NSNumber, followingEachOther: NSNumber?)
}

如果在該類型通知被廣泛應(yīng)用的場景,那么需要修改的地方就尤其多了。這顯然也是難以接受的。

EventBus

EventBus 在安卓中被廣泛地應(yīng)用,其流程如下圖所示:

圖片來源:EventBus

使用方式如下:

定義事件

 class TPFollowingChangedEvent: NSObject, TPEvent {
  	private(set) var following: Bool
  		private(set) var userID: NSNumber
}

注冊(cè)事件

TPEventBus<TPFollowingChangedEvent>.shared.register(eventType: TPFollowingChangedEvent.self, subscriber: self, selector: #selector(onEvent(event:object:)))

實(shí)現(xiàn)監(jiān)聽事件的方法

@objc func onEvent(event: TPFollowingChangedEvent, object: Any?) {
  	// do something
}

發(fā)送事件

TPEventBus.shared.post(event: event, object: self)

移除事件的注冊(cè)

TPEventBus<TPFollowingChangedEvent>.shared.unregister(eventType: TPFollowingChangedEvent.self, subscriber: self)

我們可以看到, EventBus 也是強(qiáng)類型的。

假如依然關(guān)注的場景,需要增加 followingEachOther 參數(shù),那么我們只需要在 TPFollowingChangedEvent 中增加 followingEachOther 參數(shù)即可。如下所示:

class TPFollowingChangedEvent: NSObject, TPEvent {
  	private(set) var following: Bool
  		private(set) var userID: NSNumber
  	private(set) var followingEachOther: NSNumber?
}

因此使用 EventBus 實(shí)現(xiàn)了以下需求:

  • 強(qiáng)類型
  • 可擴(kuò)展

EventBus 同 NotificationCenter 都是基于 target-action 的方案,但是我們不難將其擴(kuò)展為支持 block 監(jiān)聽的方式,并且同樣讓其能夠自動(dòng)移除事件的注冊(cè)。類似于如下的使用方式:

TPEventBus<TPFollowingChangedEvent>.shared.subscribe(eventType: TPFollowingChangedEvent.self).forObject(self).onQueue(OperationQueue.main).onEvent { (event, object) in
   // do something
}.disposed(by: self)

基于 OC, 我實(shí)現(xiàn)了一個(gè)小巧但比較全面的 EventBus 供參考:TPEventBus。

最后

我們可以看到,一對(duì)多場景中觀察者模式的應(yīng)用流程都大同小異,但是如何更好用確是值得深思的。當(dāng)然以上也只是我在一些使用場景上的思考,肯定會(huì)欠缺考慮,歡迎拍磚:blush:。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • iOS如何裁剪圓形頭像

    iOS如何裁剪圓形頭像

    這篇文章主要介紹了iOS如何裁剪圓形頭像的方法,如何為圓形頭像加邊框,如何進(jìn)行截圖操作,感興趣的小伙伴們可以參考一下
    2016-04-04
  • iOS中封裝.framework及使用的方法詳解

    iOS中封裝.framework及使用的方法詳解

    這篇文章主要給大家介紹了關(guān)于iOS中封裝.framework及使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • iOS逆向開發(fā)之微信自動(dòng)添加好友功能

    iOS逆向開發(fā)之微信自動(dòng)添加好友功能

    這篇文章主要介紹了iOS逆向開發(fā)之微信自動(dòng)添加好友功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-04-04
  • iOS在狀態(tài)欄上顯示提醒信息的功能定制

    iOS在狀態(tài)欄上顯示提醒信息的功能定制

    這篇文章主要給大家介紹了iOS在狀態(tài)欄上顯示提醒信息的相關(guān)資料,實(shí)現(xiàn)后的效果非常不錯(cuò),文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來一起看看吧。
    2017-06-06
  • iOS利用UIScrollView實(shí)現(xiàn)無限滾動(dòng)效果

    iOS利用UIScrollView實(shí)現(xiàn)無限滾動(dòng)效果

    這篇文章主要給大家介紹了iOS如何利用UIScrollView實(shí)現(xiàn)無限滾動(dòng)的效果,首先需要說明的是,文本所講的是一種"笨辦法",但是好理解且容易實(shí)現(xiàn),在圖片不多的時(shí)候用它也無妨。感興趣的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2016-12-12
  • 淺談Unity中IOS Build Settings選項(xiàng)的作用

    淺談Unity中IOS Build Settings選項(xiàng)的作用

    下面小編就為大家分享一篇淺談Unity中IOS Build Settings選項(xiàng)的作用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • iOS中containsString和rangeOfString的區(qū)別小結(jié)

    iOS中containsString和rangeOfString的區(qū)別小結(jié)

    這篇文章主要給大家總結(jié)介紹了關(guān)于iOS中containsString和rangeOfString的一些區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • iOS獲取Label高度的幾種方法與對(duì)比

    iOS獲取Label高度的幾種方法與對(duì)比

    這篇文章主要介紹了給大家介紹了iOS獲取Label高度的幾種方法,包括 view的sizeThatFits 方法、view的sizeToFit方法、NSString的sizeWithAttributes方法和NSString 的 boundingRectWithSize 方法,文中不僅介紹四種方法的實(shí)現(xiàn),還進(jìn)行了對(duì)比,下面來一起看看吧。
    2016-11-11
  • ios利用 AFN 上傳相冊(cè)或者拍照?qǐng)D片

    ios利用 AFN 上傳相冊(cè)或者拍照?qǐng)D片

    這篇文章主要介紹了ios利用 AFN 上傳相冊(cè)或者拍照?qǐng)D片的相關(guān)資料,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-06-06
  • iOS實(shí)現(xiàn)只有底部邊框線的輸入框示例代碼

    iOS實(shí)現(xiàn)只有底部邊框線的輸入框示例代碼

    這篇文章給大家分享了一種利用iOS實(shí)現(xiàn)只有底部邊框線的輸入框,其實(shí)這個(gè)效果也挺常見的,本文給出了示例代碼,下面來看看如何實(shí)現(xiàn)這種效果。
    2016-09-09

最新評(píng)論

西乡县| 吴桥县| 阳东县| 霍邱县| 宁远县| 敦煌市| 家居| 博野县| 阿拉善右旗| 年辖:市辖区| 浦城县| 大埔区| 岚皋县| 澄迈县| 平阴县| 黎川县| 西峡县| 那坡县| 平阳县| 石景山区| 东海县| 囊谦县| 钟祥市| 盖州市| 荥经县| 阿城市| 内江市| 苏尼特右旗| 商河县| 布拖县| 阿拉善右旗| 伊宁市| 玉环县| 孝昌县| 曲松县| 晋城| 石狮市| 库伦旗| 梨树县| 淅川县| 锦屏县|