2

我可以使用一些架构建议。我现在几次遇到以下问题,但我从来没有找到一种真正优雅的方法来解决它。

这个问题,尽可能在最高级别描述
我有一个父类想充当多个孩子的委托(都使用相同的协议),但是当孩子调用父母的方法时,父母不再知道哪个孩子正在打电话。

我想使用松散耦合(委托/协议或通知)而不是直接调用。我不需要多个处理程序,所以通知看起来可能有点矫枉过正。

为了说明这个问题,让我尝试一个超级简化的例子
我从一个父视图控制器(和相应的视图)开始。我创建了三个子视图并将它们中的每一个插入到父视图中。我希望每当用户触摸其中一个孩子时通知父视图控制器。有几个选项可以通知家长:

  1. 定义协议。父级实现协议并将自己设置为每个子级的委托。当用户触摸一个子视图时,它的视图控制器调用它的委托(父)。在这种情况下,父级被通知一个视图被触摸,但它不知道是哪一个。还不够好。

  2. 与#1 相同,但在协议中定义方法也传递某种标识符。当孩子告诉它的代表它被触摸时,它也会传递一个指向它自己的指针。这样,父母就可以确切地知道触摸了哪个视图。一个对象传递自己的引用似乎真的很奇怪。

  3. 使用 NSNotifications。父级为三个子级中的每一个定义一个单独的方法,然后作为通知发送者为三个子级中的每一个订阅“viewWasTouched”通知。孩子们不需要将自己附加到用户字典,但他们确实需要发送带有指向自己的指针作为范围的通知。

  4. 与 #4 相同,但不是使用单独的方法,父级可以只使用一个带有 switch case 或其他分支的方法以及通知的发送者来确定采用哪条路径。

  5. 创建多个充当子视图代表的中间人类,然后使用指向子视图的指针或其他一些差异化因素调用父视图上的方法。这种方法似乎不可扩展。

这些方法中的任何一种都被认为是最佳实践吗?我不能肯定地说,但感觉就像我错过了一些更明显/优雅的东西。

4

1 回答 1

5

您的 #2 是代表的标准 Cocoa 模式。委托协议的每条消息都将对象作为第一个参数。例如,在 中UITableViewDelegate,您会找到如下方法:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

当一个表视图将此消息发送给它的委托时,它会将自己(表视图)作为第一个参数发送。如果委托对象是多个表视图的委托,它可以使用第一个参数来确定是哪个表视图发送了消息。

当没有其他参数时,消息仍将对象作为参数,如在此UITableViewDataSource方法中:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

您会在 Cocoa Touch 框架中发现这种模式;UIPickerViewDelegate, UIImagePickerControllerDelegate, 和UINavigationControllerDelegate只是几个例子。

您应该遵循标准模式,除非您有令人信服的理由不这样做。遵循约定将使其他人(以及未来的您)更容易理解您的代码。

于 2012-07-11T03:07:12.457 回答