扩展通知中心
Extending NotificationCenter
我正在尝试为 NotificationCenter
编写扩展
我发现语法有点多 "boilerplatey",我想提供一个简单的扩展来简化发布和观察。
我可以像这样发送一个事件
NotificationCenter.dispatch(key: <#T##String#>, payload: <#T##[String : String]#>)
不过我想以类似的方式观察事件。
我正在尝试创建类似
的内容
NotificationCenter.observe(key: <#T##String#>, handler: <#T##() -> Void#>)
然而这是不正确的。我不确定如何处理传递应该在观察时触发的选择器函数?
这是我目前的尝试。
extension NotificationCenter {
static func dispatch(key: String, payload: [String: String] = [:]) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: key), object: nil, userInfo: payload)
}
static func observe(key: String, handler: ()->Void) {
NotificationCenter.default.addObserver(
self, selector: handler, name: NSNotification.Name(rawValue: key), object: nil
)
}
}
你可以这样使用:
extension NotificationCenter {
class func observe(name: NSNotification.Name, handler: @escaping (Notification) -> Void) {
self.default.addObserver(forName: name, object: nil, queue: .main, using: handler)
}
}
那么你可以这样使用它:
NotificationCenter.observe(name: UIResponder.keyboardDidShowNotification) { notification in
// do something
}
尽管如此,您绝对应该查看 https://developer.apple.com/documentation/foundation/notificationcenter/1411723-addobserver 关于注销观察的内容。
听起来你需要这样的东西
extension NotificationCenter {
static func dispatch(key: String, payload: [String: String] = [:]) {
self.default.post(name: NSNotification.Name(rawValue: key), object: nil, userInfo: payload)
}
static func observe(key: String, handler: @escaping (Notification) -> Void) {
self.default.addObserver(forName: NSNotification.Name(rawValue: key), object: nil, queue: .main, using: handler)
}
}
NotificationCenter - 一个有用但看起来笨重的界面,感觉代码有点臃肿,因为有人来自 UNIX-like 线程同步语义......所以,这些扩展基于 S.O . & the 'Net, with a couple twists.
extension Notification.Name {
static let patientlyWaiting = Notification.Name("patientlyWaiting")
// .
// . list your arbitrary waiter names here...
// .
}
extension NotificationCenter {
static func wait(_ name : Notification.Name) async {
for await _ in NotificationCenter.default.notifications(named: name) {
break;
}
}
static func post(_ name : Notification.Name) {
NotificationCenter.default.post(name: name, object: nil)
}
static func postProcessing(_ name: Notification.Name, using block: @escaping (Notification) -> Void) {
NotificationCenter.default.addObserver(forName: name, object: nil, queue: OperationQueue.main, using: block)
}
}
要使用它,像这样:
等待通知:
@IBAction func doSomethingAsychronouslyButtonPushed(_ sender: Any) {
doSomethingAsynchronously()
NotificationCenter.postProcessing(.patientlyWaiting, using: { _ in
print("doSomethingAsynchronouslyButton completion handler called")
})
}
通知中:
func doSomethingAsynchronously() {
for n in ["Time", " ", "consuming", " - ", "whatever"] {
print("\(n)", terminator: "")
}
print("\n")
NotificationCenter.post(.patientlyWaiting)
}
注意:您可以避免使用闭包并使用 Swift 语言的 recently-added async
/[=14= 进行内联等待] 支持(参见'wait()function in the extensions shown above), but I didn't provide an example of using that because I haven't been able to invoke
asyncfunctions from selectors, such as from a
UIButtonpress, directly or indirectly; because, any function that uses
awaitneeds to be declared
async. Specifically, #selector(afunc(_:)) doesn't match functions declared
async, and I'm unaware of a function signature syntax that accounts for an
asyncin function declaration (to pass to
#选择器()`)。如果有人知道,请在评论中告诉我,我会更新答案。
我正在尝试为 NotificationCenter
我发现语法有点多 "boilerplatey",我想提供一个简单的扩展来简化发布和观察。
我可以像这样发送一个事件
NotificationCenter.dispatch(key: <#T##String#>, payload: <#T##[String : String]#>)
不过我想以类似的方式观察事件。
我正在尝试创建类似
的内容NotificationCenter.observe(key: <#T##String#>, handler: <#T##() -> Void#>)
然而这是不正确的。我不确定如何处理传递应该在观察时触发的选择器函数?
这是我目前的尝试。
extension NotificationCenter {
static func dispatch(key: String, payload: [String: String] = [:]) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: key), object: nil, userInfo: payload)
}
static func observe(key: String, handler: ()->Void) {
NotificationCenter.default.addObserver(
self, selector: handler, name: NSNotification.Name(rawValue: key), object: nil
)
}
}
你可以这样使用:
extension NotificationCenter {
class func observe(name: NSNotification.Name, handler: @escaping (Notification) -> Void) {
self.default.addObserver(forName: name, object: nil, queue: .main, using: handler)
}
}
那么你可以这样使用它:
NotificationCenter.observe(name: UIResponder.keyboardDidShowNotification) { notification in
// do something
}
尽管如此,您绝对应该查看 https://developer.apple.com/documentation/foundation/notificationcenter/1411723-addobserver 关于注销观察的内容。
听起来你需要这样的东西
extension NotificationCenter {
static func dispatch(key: String, payload: [String: String] = [:]) {
self.default.post(name: NSNotification.Name(rawValue: key), object: nil, userInfo: payload)
}
static func observe(key: String, handler: @escaping (Notification) -> Void) {
self.default.addObserver(forName: NSNotification.Name(rawValue: key), object: nil, queue: .main, using: handler)
}
}
NotificationCenter - 一个有用但看起来笨重的界面,感觉代码有点臃肿,因为有人来自 UNIX-like 线程同步语义......所以,这些扩展基于 S.O . & the 'Net, with a couple twists.
extension Notification.Name {
static let patientlyWaiting = Notification.Name("patientlyWaiting")
// .
// . list your arbitrary waiter names here...
// .
}
extension NotificationCenter {
static func wait(_ name : Notification.Name) async {
for await _ in NotificationCenter.default.notifications(named: name) {
break;
}
}
static func post(_ name : Notification.Name) {
NotificationCenter.default.post(name: name, object: nil)
}
static func postProcessing(_ name: Notification.Name, using block: @escaping (Notification) -> Void) {
NotificationCenter.default.addObserver(forName: name, object: nil, queue: OperationQueue.main, using: block)
}
}
要使用它,像这样:
等待通知:
@IBAction func doSomethingAsychronouslyButtonPushed(_ sender: Any) {
doSomethingAsynchronously()
NotificationCenter.postProcessing(.patientlyWaiting, using: { _ in
print("doSomethingAsynchronouslyButton completion handler called")
})
}
通知中:
func doSomethingAsynchronously() {
for n in ["Time", " ", "consuming", " - ", "whatever"] {
print("\(n)", terminator: "")
}
print("\n")
NotificationCenter.post(.patientlyWaiting)
}
注意:您可以避免使用闭包并使用 Swift 语言的 recently-added async
/[=14= 进行内联等待] 支持(参见'wait()function in the extensions shown above), but I didn't provide an example of using that because I haven't been able to invoke
asyncfunctions from selectors, such as from a
UIButtonpress, directly or indirectly; because, any function that uses
awaitneeds to be declared
async. Specifically, #selector(afunc(_:)) doesn't match functions declared
async, and I'm unaware of a function signature syntax that accounts for an
asyncin function declaration (to pass to
#选择器()`)。如果有人知道,请在评论中告诉我,我会更新答案。