- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
如果委托(delegate)是为对象之间的一对一关系设计的,而 NSNotifications 是为一对多的潜在关系设计的,那么是否有针对一对多的最佳实践?
我在 iOS 中看到过很多自定义多播委托(delegate),其中一个对象可以转换到多个订阅者(即 Swift Language Multicast Delegate ),但实现通常非常复杂并且看起来有点矫枉过正。一个这样的问题是安全地存储一组弱引用(委托(delegate))(How do I declare an array of weak references in Swift?)。
我看过很多建议(比如这个 multiple listeners for delegate iOS ),这些建议表明这就是 NotificationCenter 的用途。但是,为一对多的关系向以太广播的想法本身似乎有点过分了。
Apple 的框架和 Swift 语言是否有最佳实践?我从来没有看到他们写过这个。 NotificationCenter 是否适合用于一对多关系,否则需要多播委托(delegate)?
最佳答案
我不会使用 NotificationCenter
,因为发送者和接收者(观察者)之间的消息类型和数据会丢失。使用 Notification Center
将使您的代码依赖于 Notification
对象,您需要使用通知的 userInfo
字典来添加数据,这使得更难理解到底是什么保留了通知(需要查看发送通知时数据的填充方式)。
委托(delegate)是一个更好的解决方案,在弱委托(delegate)列表中有超过 1 个委托(delegate)是可以的。我在很多地方使用过这样的组合,在这些地方我需要为特定事件注册超过 1 个监听器并且工作正常。
您可以创建一次委托(delegate)集合并在代码中非常轻松地重用它。这是我的解决方案:
class WeakContainer {
private weak var value: AnyObject?
public init(value: AnyObject) {
self.value = value
}
func get() -> AnyObject? {
return self.value
}
}
class DelegatesCollection<T>: Sequence {
private lazy var weakDelegates = [WeakContainer]()
var delegates: [T] {
return self.weakDelegates.map() { $0.get() as! T }
}
var hasDelegates: Bool {
return !self.weakDelegates.isEmpty
}
init() { }
func add(delegate: T) {
var exists = false
for currentDelegate in self.weakDelegates {
if(currentDelegate.get() === (delegate as AnyObject)) {
exists = true
break
}
}
if(!exists) {
self.weakDelegates.append(WeakContainer(value: delegate as AnyObject))
}
}
func remove(delegate: T) {
var i = 0
for currentDelegate in self.weakDelegates {
if(currentDelegate.get() == nil || currentDelegate.get() === (delegate as AnyObject)) {
self.weakDelegates.remove(at: i)
break
}
i += 1
}
}
func makeIterator() -> IndexingIterator<[T]> {
return self.delegates.makeIterator()
}
}
我可以推测 Apple 框架只使用单个委托(delegate),因为调用委托(delegate)时要执行的操作是业务逻辑。从 Apple 的角度来看,委托(delegate)某个事件已经发生并让应用程序决定下一步做什么就足够了,因此在框架级别支持多个委托(delegate)是没有意义的。
关于ios - 对于一对多的关系 : NotificationCenter or multicasting delegate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55753871/
我看了很多文章,但我仍然不清楚我们通常创建的普通委托(delegate)和多播委托(delegate)之间的区别。 public delegate void MyMethodHandler(objec
考虑以下几点: Action a1 = new Action(_insert); Action a2 = new Action(a1); a2 指的是什么?它是 a1,a1 的浅拷贝还是 a1 的深拷
我希望这听起来像是一个显而易见的问题,但是委托(delegate)返回类型是否也必须与其委托(delegate)的方法的返回类型相匹配? EG,像这样: public static void Save
我想使用 Kotlin 委托(delegate),但我不想在委托(delegate)人之外创建委托(delegate)。委托(delegate)的所有示例都如下所示: interface Worker
class SuperClass { var delegate : SuperClassDelegate? } protocol SuperClassDelegate { func d
我有一个加载 View 的 View ,需要将 View 推送到主导航 Controller 。 我已经为每个 View 设置了一个委托(delegate),并且基本上使我的调用沿着“链”返回到主导航
为简单起见,假设我想创建一个自定义 UITextField 并向其添加一个简单的行为;也就是说,如果文本字段成为第一响应者,背景颜色将变为绿色。 为此,在我的自定义类中,我必须将该类设置为委托(del
我非常有信心我应该能够使用非静态方法的委托(delegate),但下面给了我一个错误: public class TestClass { private delegate void TestD
在 C# 中不能从 System.Delegate 或 System.MulticastDelegate 继承。只要您声明标准的“运行时托管”方法,就完全可以在 MSIL 中执行此操作。但是,每次我向
我在 Storyboard 中定义了一个 iPad 界面,带有一个 SplitViewController。我想将 SplitViewController 的委托(delegate)设置为指向详细 C
我有几个解析器。有一个顶级的可以委托(delegate)给另一个。 Parser我们从 Reader 中获取他们的输入(可变)。我只想要一个 Parser为了能够一次解析,只有一个解析器应该有 Rea
一直以来我都在阅读关于反射的文章,每个人都在说:“反射很慢”,“反射很慢”。 现在我决定测试速度有多慢,令我惊讶的是,使用反射创建的委托(delegate)实际上是使用 lambda 创建的委托(de
在 Xcode 4.5 中启动了 Cocos2D 2.1 模板(没有物理引擎),针对 iOS 6 和 iPad。在 CDAudioManager.m 文件中,以下代码... AVAudioSessio
以下是来自未管理的 dll 的函数代码。它接受一个函数指针作为参数,并简单地返回被调用函数返回的值。 extern __declspec(dllexport) int _stdcall callDe
//NewCharts.h #import @interface NewCharts : UIViewController @property(nonatomic,retain)IBOutlet U
鉴于以下 MSDN 示例代码,为什么我不能定义 Action 委托(delegate)“内联”: public static void Main(string[] args) { Action
在虚幻引擎中,UFUNCTION用于通过附加说明符来丰富功能,以用于蓝图使用、复制和委托(delegate)。 然而,一些委托(delegate)类型似乎不允许绑定(bind) UFUNCTION(如
我刚刚将照片选择器放入我的项目中,一切正常。唯一的事情是它坚持在我设置委托(delegate)的地方给我以下警告 - Assigning to 'id' from incompatible type
我有一个 UIImageView 的子类,并且想将 self 作为参数传递给委托(delegate)。我在 MyImageView 之前收到错误“预期 ')'”。我需要将对象传递给委托(delegat
我正在开发 iOS 10 的语音转文本功能。 我希望调用 SFSpeechRecognitionTaskDelegate 的委托(delegate)方法来检查完成的结果。 func speechRec
我是一名优秀的程序员,十分优秀!