7

考虑以下常见情况:

您的 Cocoa 应用程序中有一些MainView从 NIB 加载,由MainViewController. 您MainView包含一些控件,例如UILabel infoLabel. 您还有一个MyDelegate接收某种事件的委托类。

您想确保在MyDelegate收到其事件时,infoLabel适当地更新。但是,问题在于MyDelegate没有对 theMainView或 the的引用MainViewController并且不知道标签。

一种解决方案是传递MainViewController对委托对象的引用,但这感觉不对,因为您可能会发现自己处于对象具有彼此引用的不良情况。

解决这个问题的正确设计是什么?

4

4 回答 4

4

在一个未具名的开发者论坛中,有人写道:

所以,长话短说,我决定开始使用 NSNotifications。人们一直在关注的斯坦福在线课程是由两名苹果工程师教授的。他们刚刚明确表示不要使用应用程序委托或全局变量,并表示要使用 NSNotifications、委托和 KV 观察。

如果这是苹果工程师所说的,我将朝着这个方向前进。

NSNotifications 非常巧妙,因为它们并没有真正干扰封装。监听器只监听通知和一个对象——我认为它不必知道或关心是谁发送的。

因此,在您的示例中,我会考虑让代表发布标签已更改的通知,或者如果可能的话,最好让控制器观察该属性。

于 2009-05-04T18:07:03.577 回答
2

以下是我想到的 2 个选项:

  • 如果要委托的事件是由您的控制器发送的,您可以让该方法向控制器返回一个值以推送到视图。

  • 您还可以将 infoLabel 的值绑定到某个键(例如,使用 Cocoa 绑定或仅使用原始键值观察)。绑定对象(可以是委托或其他模型对象)可以只更新绑定键,这会将值推送到 infoLabel。例如,您可以将委托的“info”成员绑定到 infoLabel 的值。当代理接收到一个事件时,它可以更新信息成员,并且视图发生变化。实际绑定本身可能发生在 IB 中(如果您的委托在 nib 中)或控制器(它具有对视图和委托的引用。)

后一种解决方案基本上是一个循环引用,但对我来说似乎更干净。

于 2009-05-04T17:33:18.463 回答
0

我们实现了一个棘手的“数据”对象,它控制了几乎所有的东西。它检查是否有更改并保持所有全局变量的更新。

创建新实例时,我指的是 Data 类,如下所示:

[[Button alloc] initWithData:data]];

data单例数据类在哪里。现在我们可以检查是否需要做出响应的更改。

我承认,它仍然需要像你描述的那样引用。似乎没有parent嵌入一个简单的参考。

于 2009-05-04T17:16:08.693 回答
-1

正如您所说,通常的模式是MainView通过其委托方法传递一个指针。因此,如果MainView正在调用其委托的doSomethingWithFoo:方法,您希望将该方法更改为:

- (void)mainView:(MainView *)view doSomethingWithFoo:(id)foo

并相应地调用新方法。如果直接对 MainView 指针进行操作,循环引用应该不会有任何问题。

于 2009-05-04T17:12:47.077 回答