【问题标题】:NSNotifications vs delegate for multiple instances of same protocolNSNotifications 与同一协议的多个实例的委托
【发布时间】:2012-07-11 02:07:55
【问题描述】:

我可以使用一些架构建议。我已经多次遇到以下问题,但我从未找到真正优雅的方法来解决它。

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

我想使用松散耦合(委托/协议或通知)而不是直接调用。我不需要多个处理程序,因此通知似乎有些过头了。

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

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

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

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

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

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

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

【问题讨论】:

    标签: objective-c delegates protocols nsnotifications nsnotification


    【解决方案1】:

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

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

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

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

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

    您会在整个 Cocoa Touch 框架中找到这种模式; UIPickerViewDelegateUIImagePickerControllerDelegateUINavigationControllerDelegate 只是几个例子。

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

    【讨论】:

    • 太棒了!我想我会同意的。
    • 谢谢罗伯。你能澄清一下“弄清楚”吗?在设置代表时,我应该存储子 ID 的地图吗?还是有一种标准的方式来“标记”风投?我知道将 view.tag 用于视图,但 VC 似乎没有为此目的的等效属性。
    • 我发现this question 建议使用 VC.view.tag,如果它没有被用于其他任何事情,这是有道理的。但我最终只是简单地存储了最后一个 segue 的名称,因为我一次只显示一个孩子。
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多