Ios 多通知的最佳方法:委托与KVO

Ios 多通知的最佳方法:委托与KVO,ios,objective-c,delegates,key-value-observing,Ios,Objective C,Delegates,Key Value Observing,我有三个类共享NSObject子类的相同实例 所有这三个类都可以修改该共享实例属性,当这种情况发生时,该共享实例必须通知所有其他三个类X变量已更改 这是使用KVO的完美场景,但我认为这是一个非常不一致的代码,有很多硬编码字符串,因此没有编译时警告或检查发生,当出现问题时很难获得stacktrace,在重构代码的情况下,更改所有内容并祈祷不要忘记任何内容是一件令人头痛的事情,取消分配时手动删除观察者,通过向所有类添加相同的观察者等重复大量代码 由于这个原因,我认为,委托可能是解决大多数(如果不是全

我有三个类共享
NSObject
子类的相同实例

所有这三个类都可以修改该共享实例属性,当这种情况发生时,该共享实例必须通知所有其他三个类
X
变量已更改

这是使用
KVO
的完美场景,但我认为这是一个非常不一致的代码,有很多硬编码字符串,因此没有编译时警告或检查发生,当出现问题时很难获得stacktrace,在重构代码的情况下,更改所有内容并祈祷不要忘记任何内容是一件令人头痛的事情,取消分配时手动删除观察者,通过向所有类添加相同的观察者等重复大量代码

由于这个原因,我认为,
委托
可能是解决大多数(如果不是全部)问题的好办法。易于实现,非常清晰且有文档记录,如果编译器告诉您有什么变化,无需手动设置为nil,无需硬编码字符串,出现错误时有明显的stracktrace等

我的
delegate
方法将覆盖所有变量的
setter
,我希望监听它们的更改,并在那里调用委托,以便所有类都可以知道该更改

你认为这种方法怎么样


提前谢谢你

虽然您完全正确,但KVO的关键路径需要硬编码字符串,我可以说,在几个大型应用程序上工作,这很少是一个问题

代理解决方案会起作用,但是您需要跟踪代理(在您的情况下,听起来您需要跟踪一组代理)。您处理此问题的方式与无论如何使用KVO注册/注销的方式类似

您描述的问题正是观察者模式应该解决的问题,Cocoa为您提供了该模式的内置解决方案

我的建议(大部分您可能知道):
1) 键路径的
extern
常量,所有3个类都可以使用
2) 当您的一个观察者收到对对象的引用时,请使用
-addObserver:…

3) 确保正确调用
-removeObserver:…

4) 在
-observeValueForKeyPath:…
中,将密钥路径与常量进行比较,并将处理放在其中

但正如您所提到的,可能出现的主要问题是关键路径是否改变。您的代码仍将编译,并且您不一定会在运行时立即发现问题

如果这是一个真正的问题,那么您可以编写一个包装器方法来调用
-addObserver:…
,但首先检查接收方是否响应
keyPath
参数

虽然我从来没有这样做过,正如我提到的,我从来没有真正解决过KVO的关键路径问题。通常,如果有人进入并重命名密钥路径,他们会进行工作区搜索,并看到硬编码字符串也需要更改


总之,我个人更喜欢KVO解决方案,而不是代理通知解决方案,但最终你是对的,你可能会错过错误w/KVO

虽然你完全正确,但你需要硬编码字符串作为KVO的关键路径,我可以说是轶事,在几个大型应用程序上工作,这很少是一个问题

代理解决方案会起作用,但是您需要跟踪代理(在您的情况下,听起来您需要跟踪一组代理)。您处理此问题的方式与无论如何使用KVO注册/注销的方式类似

您描述的问题正是观察者模式应该解决的问题,Cocoa为您提供了该模式的内置解决方案

我的建议(大部分您可能知道):
1) 键路径的
extern
常量,所有3个类都可以使用
2) 当您的一个观察者收到对对象的引用时,请使用
-addObserver:…

3) 确保正确调用
-removeObserver:…

4) 在
-observeValueForKeyPath:…
中,将密钥路径与常量进行比较,并将处理放在其中

但正如您所提到的,可能出现的主要问题是关键路径是否改变。您的代码仍将编译,并且您不一定会在运行时立即发现问题

如果这是一个真正的问题,那么您可以编写一个包装器方法来调用
-addObserver:…
,但首先检查接收方是否响应
keyPath
参数

虽然我从来没有这样做过,正如我提到的,我从来没有真正解决过KVO的关键路径问题。通常,如果有人进入并重命名密钥路径,他们会进行工作区搜索,并看到硬编码字符串也需要更改


总之,我个人更喜欢KVO解决方案,而不是委托通知解决方案,但最终你是对的,因为你可能会错过错误w/KVO

共享实例子类只有一个带有
n
可选方法的协议。其他类必须实现该协议才能侦听共享实例更改。您是否考虑过使用NotificationCenter进行多个通知?
NSNotificationCenter
KVO
非常相似,但
KVO
仅用于控制变量,这正是我需要的。因此,
NSNotificationCenter
的问题与使用
KVO
时的问题完全相同:硬编码字符串、重构时的头痛、未记录、重复代码等……共享实例子类只有一个带有
n
选项的协议