在Swift中,注册"anywhere"成为一个协议的委托人
In Swift, register "anywhere" to be a delegate of a protocol
我有一个复杂的观点class,
class Snap:UIViewController, UIScrollViewDelegate
{
}
最终结果是用户可以选择一种颜色...
protocol SnapProtocol:class
{
func colorPicked(i:Int)
}
class Snap:UIViewController, UIScrollViewDelegate
{
someDelegate.colorPicked(blah)
}
那么谁来处理呢。
假设您确定响应链上有一些东西,甚至遍历容器视图,这是一个SnapProtocol
。如果是这样,您可以使用 来调用它
var r : UIResponder = self
repeat { r = r.nextResponder()! } while !(r is SnapProtocol)
(r as! SnapProtocol).colorPicked(x)
如果您愿意,可以使用这个最高级的扩展程序
public extension UIResponder // walk up responder chain
{
public func next<T>() -> T?
{
guard let responder = self.nextResponder()
else { return nil }
return (responder as? T) ?? responder.next()
}
}
courtesy these guys 并安全地找到你上面的任何 SnapProtocol
,
(next() as SnapProtocol?)?.colorPicked(x)
太好了。
但是。如果想要获得 colorPicked
的对象是一个远离你的骑士移动,沿着一些复杂的侧链,and/or 你甚至不知道哪个对象想要它。
我目前的解决方案是这样的,我有一个单例 "game manager" -like class,
public class .. a singleton
{
// anyone who wants a SnapProtocol:
var useSnap:SnapProtocol! = nil
}
有些变态class,哪里都想吃SnapProtocol ...
class Dinosaur:NSObject, SnapProtocol
{
....
func colorPicked(index: Int)
{...}
...所以,要将其设置为所需的委托,请使用单例
thatSingleton.useSnap = dinosaur
很明显,这很好用。
另请注意,我可以轻松地在单例中编写一个小系统,以便该协议的任意数量的用户都可以动态地 register/deregister 那里并接听电话。
但它有明显的问题,它不是很 "pattern" 并且看起来非常不合惯用语。
所以。我真的在 Swift 环境中以正确的方式这样做吗?
我真的把自己弄糊涂了吗,我应该在今天的 iOS 中使用一些完全不同的模式来发送这样的 "messages to anyone who wants them?" 。 .. 也许我什至不应该使用协议?
"Send out messages to anyone who wants them" 几乎就是 NSNotificationCenter
的描述。
没错,它不是从一开始就为 Swift 模式设计的 API,例如闭包、强类型和面向协议的编程。 (如其他 comments/answers 所述,如果您确实需要此类功能,开源 SwiftNotificationCenter 是一个不错的选择。)
然而,NSNotificationCenter
稳健且久经沙场 — 它是每次通过 运行循环。
这是在 Swift 中使用 NSNotificationCenter 的非常简洁的操作方法:
Swift标准中没有"protocol based"通知机制
库或运行时。可以在此处找到一个不错的实现 https://github.com/100mango/SwiftNotificationCenter。来自自述文件:
A Protocol-Oriented NotificationCenter which is type safe, thread safe
and with memory safety.
Type Safe
No more userInfo dictionary and Downcasting, just deliver the concrete
type value to the observer.
Thread Safe
You can register, notify, unregister in any thread without crash and
data corruption.
Memory Safety
SwiftNotificationCenter store the observer as a zeroing-weak
reference. No crash and no need to unregister manually.
It's simple, safe, lightweight and easy to use for one-to-many
communication.
使用 SwiftNotificationCenter,符合 class 的(a 的实例)可以像这样注册自己:
class MyObserver: SnapProtocol {
func colorPicked(i: Int) {
print("color picked:", i)
}
init() {
NotificationCenter.register(SnapProtocol.self, observer: self)
}
}
并且向所有符合要求的注册观察员广播通知
完成为
NotificationCenter.notify(SnapProtocol.self) {
[=11=].colorPicked(x)
}
我有一个复杂的观点class,
class Snap:UIViewController, UIScrollViewDelegate
{
}
最终结果是用户可以选择一种颜色...
protocol SnapProtocol:class
{
func colorPicked(i:Int)
}
class Snap:UIViewController, UIScrollViewDelegate
{
someDelegate.colorPicked(blah)
}
那么谁来处理呢。
假设您确定响应链上有一些东西,甚至遍历容器视图,这是一个SnapProtocol
。如果是这样,您可以使用
var r : UIResponder = self
repeat { r = r.nextResponder()! } while !(r is SnapProtocol)
(r as! SnapProtocol).colorPicked(x)
如果您愿意,可以使用这个最高级的扩展程序
public extension UIResponder // walk up responder chain
{
public func next<T>() -> T?
{
guard let responder = self.nextResponder()
else { return nil }
return (responder as? T) ?? responder.next()
}
}
courtesy these guys 并安全地找到你上面的任何 SnapProtocol
,
(next() as SnapProtocol?)?.colorPicked(x)
太好了。
但是。如果想要获得 colorPicked
的对象是一个远离你的骑士移动,沿着一些复杂的侧链,and/or 你甚至不知道哪个对象想要它。
我目前的解决方案是这样的,我有一个单例 "game manager" -like class,
public class .. a singleton
{
// anyone who wants a SnapProtocol:
var useSnap:SnapProtocol! = nil
}
有些变态class,哪里都想吃SnapProtocol ...
class Dinosaur:NSObject, SnapProtocol
{
....
func colorPicked(index: Int)
{...}
...所以,要将其设置为所需的委托,请使用单例
thatSingleton.useSnap = dinosaur
很明显,这很好用。
另请注意,我可以轻松地在单例中编写一个小系统,以便该协议的任意数量的用户都可以动态地 register/deregister 那里并接听电话。
但它有明显的问题,它不是很 "pattern" 并且看起来非常不合惯用语。
所以。我真的在 Swift 环境中以正确的方式这样做吗?
我真的把自己弄糊涂了吗,我应该在今天的 iOS 中使用一些完全不同的模式来发送这样的 "messages to anyone who wants them?" 。 .. 也许我什至不应该使用协议?
"Send out messages to anyone who wants them" 几乎就是 NSNotificationCenter
的描述。
没错,它不是从一开始就为 Swift 模式设计的 API,例如闭包、强类型和面向协议的编程。 (如其他 comments/answers 所述,如果您确实需要此类功能,开源 SwiftNotificationCenter 是一个不错的选择。)
然而,NSNotificationCenter
稳健且久经沙场 — 它是每次通过 运行循环。
这是在 Swift 中使用 NSNotificationCenter 的非常简洁的操作方法:
Swift标准中没有"protocol based"通知机制 库或运行时。可以在此处找到一个不错的实现 https://github.com/100mango/SwiftNotificationCenter。来自自述文件:
A Protocol-Oriented NotificationCenter which is type safe, thread safe and with memory safety.
Type Safe
No more userInfo dictionary and Downcasting, just deliver the concrete type value to the observer.
Thread Safe
You can register, notify, unregister in any thread without crash and data corruption.
Memory Safety
SwiftNotificationCenter store the observer as a zeroing-weak reference. No crash and no need to unregister manually.
It's simple, safe, lightweight and easy to use for one-to-many communication.
使用 SwiftNotificationCenter,符合 class 的(a 的实例)可以像这样注册自己:
class MyObserver: SnapProtocol {
func colorPicked(i: Int) {
print("color picked:", i)
}
init() {
NotificationCenter.register(SnapProtocol.self, observer: self)
}
}
并且向所有符合要求的注册观察员广播通知 完成为
NotificationCenter.notify(SnapProtocol.self) {
[=11=].colorPicked(x)
}