扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇文章为大家展示了iOS中怎么实现跨页面状态同步,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
成都创新互联是一家专注于网站建设、成都网站设计与策划设计,铜鼓网站建设哪家好?成都创新互联做网站,专注于网站建设十载,网设计领域的专业建站公司;建站业务涵盖:铜鼓等地区。铜鼓做网站价格咨询:18982081108NotificationCenter
状态同步实际是一对多的场景,也就是一个事件可以被多个观察者监听到。而苹果的系统框架自带的 NotificationCenter 正是用来适配这种场景,并且其也是被系统框架本身及我们开发者大面积使用的。用法如下:
定义通知名字,以及需要额外传递信息的 key
基于 target-action 的方式注册通知
open func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)
实现监听通知的方法
func onReceivedNotification(note: NSNotification)
发送通知,可以传递发送通知的对象(object)以及一些额外的信息(userInfo)
open func post(name aName: NSNotification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable : Any]? = nil)
移除注册的通知
open func removeObserver(_ observer: Any, name aName: NSNotification.Name?, object anObject: Any?)
当然 NotificationCenter 也提供了一种更加便利基于 block 的方式注册监听通知,其将 2,3 两个步骤整合为 1 个步骤。
open func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol
整体流程很清晰,简单易用,但是却有一个严重的缺点 —— 弱类型。我们接收到的是一个NSNotification
对象。
open class NSNotification : NSObject, NSCopying, NSCoding { open var name: NSNotification.Name { get } open var object: Any? { get } open var userInfo: [AnyHashable : Any]? { get } }
假设我们需要传递一个关注状态改变的信息,那么需要包含关注更改后的状态以及被关注者的 ID。那么我们需要从 userInfo 中取出所需要的值:
let following = notification.userInfo["FollowingKey"] as! NSNumber let userID = notification.userInfo["UserIDKey"] as! NSNumber;
也就是说接收通知的一方一般需要要查看文档才知道怎样从 userInfo 取值,取的值的类型又是什么。这对于使用是极为不方便的。
SwiftNotificationCenter
SwiftNotificationCenter是一种面向协议的通知中心方案。使用方式如下:
定义协议
protocol FollowingChanged { func followingDidChange(following: Bool, userID: NSNumber) }
基于协议注册通知
Broadcaster.register(Update.self, observer: observer)
实现协议方法
extension ViewController: FollowingChanged { func followingDidChange(following: Bool, userID: NSNumber) { // do something } }
发送通知
Broadcaster.notify(FollowingChanged.self) { $0.followingDidChange(following, userID) }
移除注册的通知
Broadcaster.unregister(Update.self, observer: observer)
我们可以看到,其基于协议的方式解决了弱类型的问题,并且其通过AssociatedObject
实现了通知的自动移除。但其也存在着扩展性较差的问题。
依然是关注改变的场景,假如随着业务的发展,有的地方需要知道关注后是否为互关的状态,那么又需要增加一个字段来标识。因此我们需要修改协议,增加参数,且由于其不是必须传递的参数,因此是 optional 类型。
protocol FollowingChanging { func followingDidChange(following: Bool, userID: NSNumber, followingEachOther: NSNumber?) }
如果在该类型通知被广泛应用的场景,那么需要修改的地方就尤其多了。这显然也是难以接受的。
EventBus
EventBus 在安卓中被广泛地应用,其流程如下图所示:
图片来源:EventBus
使用方式如下:
定义事件
class TPFollowingChangedEvent: NSObject, TPEvent { private(set) var following: Bool private(set) var userID: NSNumber }
注册事件
TPEventBus.shared.register(eventType: TPFollowingChangedEvent.self, subscriber: self, selector: #selector(onEvent(event:object:)))
实现监听事件的方法
@objc func onEvent(event: TPFollowingChangedEvent, object: Any?) { // do something }
发送事件
TPEventBus.shared.post(event: event, object: self)
移除事件的注册
TPEventBus.shared.unregister(eventType: TPFollowingChangedEvent.self, subscriber: self)
我们可以看到, EventBus 也是强类型的。
假如依然关注的场景,需要增加 followingEachOther 参数,那么我们只需要在 TPFollowingChangedEvent 中增加 followingEachOther 参数即可。如下所示:
class TPFollowingChangedEvent: NSObject, TPEvent { private(set) var following: Bool private(set) var userID: NSNumber private(set) var followingEachOther: NSNumber? }
因此使用 EventBus 实现了以下需求:
强类型
可扩展
EventBus 同 NotificationCenter 都是基于 target-action 的方案,但是我们不难将其扩展为支持 block 监听的方式,并且同样让其能够自动移除事件的注册。类似于如下的使用方式:
TPEventBus.shared.subscribe(eventType: TPFollowingChangedEvent.self).forObject(self).onQueue(OperationQueue.main).onEvent { (event, object) in // do something }.disposed(by: self)
上述内容就是iOS中怎么实现跨页面状态同步,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联网站建设公司行业资讯频道。
另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流