我有一个复杂的 View 类,
class Snap:UIViewController, UIScrollViewDelegate
{
}
最终结果是用户可以选择一种颜色...
protocol SnapProtocol:class
{
func colorPicked(i:Int)
}
class Snap:UIViewController, UIScrollViewDelegate
{
someDelegate.colorPicked(blah)
}
那么谁来处理它。
假设您肯定知道响应者链上游有一些东西,甚至遍历容器 View ,它是 SnapProtocol
。如果是这样,您可以使用 this lovely code调用它
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
的对象是骑士移动远离你,沿着一些复杂的侧链,和/或你甚至不知道哪个对象想要它怎么办。
我目前的解决方案是这样的,我有一个单例“游戏经理”类,
public class .. a singleton
{
// anyone who wants a SnapProtocol:
var useSnap:SnapProtocol! = nil
}
一些古怪的类,在任何地方,都想吃掉 SnapProtocol ...
class Dinosaur:NSObject, SnapProtocol
{
....
func colorPicked(index: Int)
{...}
...所以,要将其设置为所需的委托(delegate),请使用单例
thatSingleton.useSnap = dinosaur
很明显,这工作正常。
另请注意,我可以轻松地在单例中编写一个小系统,以便该协议(protocol)的任何数量的用户都可以在那里动态注册/注销并获得调用。
但它有明显的问题,它不是很“模式”,而且看起来非常不惯用。
所以。我真的在 Swift 环境中以正确的方式这样做吗?
我真的把自己弄糊涂了吗,在今天的 iOS 中我应该使用一些完全不同的模式来发送这样的“消息给任何需要它们的人?” ...也许我应该甚至不使用协议(protocol)?
最佳答案
“向任何需要的人发送消息”几乎就是对 NSNotificationCenter
的描述。 .
的确,它不是从一开始就为 Swift 模式(例如闭包、强类型和面向协议(protocol)的编程)设计的 API。 (如其他评论/答案中所述,如果您确实需要此类功能,开源 SwiftNotificationCenter 是一个不错的选择。)
但是,NSNotificationCenter
是健壮且久经考验的——它是在每次通过运行循环时在数百个对象之间发送的数千条消息的基础。
这是在 Swift 中使用 NSNotificationCenter 的非常简洁的方法:
关于ios - 在 Swift 中,将 "anywhere"注册为协议(protocol)的委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37658991/