Bre*_*aut 2 delegates protocols objective-c nsnotifications nsnotification
我可以使用一些建筑建议.我现在遇到了几次以下问题,我从来没有找到一种真正优雅的方法来解决它.
问题,尽可能在最高级别描述:
我有一个父类,希望充当多个孩子的代理(都使用相同的协议),但是当孩子们在父母上调用方法时,父母不再知道哪个孩子正在打电话.
我想使用松散耦合(委托/协议或通知)而不是直接调用.我不需要多个处理程序,因此通知看起来可能有点矫枉过正.
为了说明这个问题,让我尝试一个超简化的例子:
我从父视图控制器(和相应的视图)开始.我创建了三个子视图,并将它们中的每一个插入到父视图中.我想在用户触摸其中一个孩子时通知父视图控制器.有几个选项可以通知父母:
定义协议.父实现协议并将其自身设置为每个子代的委托.当用户触摸子视图时,其视图控制器调用其委托(父代).在这种情况下,通知父母一个视图被触摸,但它不知道哪一个.还不够好.
与#1相同,但定义协议中的方法也传递某种标识符.当孩子告诉其代表它被触摸时,它也会传递指向自身的指针.这样,父母就知道确切地触摸了哪个视图.对象传递自身的引用似乎很奇怪.
使用NSNotifications.父级为三个子节点中的每一个定义一个单独的方法,然后为这三个子节点中的每一个订阅"viewWasTouched"通知作为通知发送方.孩子们不需要将自己附加到用户词典,但他们确实需要发送带有指针的通知作为范围.
与#4相同,但不是使用单独的方法,父级可以使用带有switch case或其他分支的方法以及通知的发送方来确定要采用的路径.
创建多个中间人类,充当子视图的委托,然后使用指向子节点的指针或其他一些区分因子调用父节点上的方法.这种方法似乎不具备可扩展性.
这些方法中的任何一种都是最佳实践吗?我不能肯定地说,但感觉我错过了一些更明显/优雅的东西.
你的#2是代表的标准Cocoa模式.委托协议的每条消息都将对象作为第一个参数.例如,UITableViewDelegate
你在这里找到这样的方法:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
Run Code Online (Sandbox Code Playgroud)
当表视图将此消息发送给其委托时,它将自身(表视图)作为第一个参数发送.如果委托对象是多个表视图的委托,则它可以使用第一个参数来确定哪个表视图发送了消息.
如果没有其他参数,则消息仍将对象作为参数,如此UITableViewDataSource
方法:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
Run Code Online (Sandbox Code Playgroud)
你会在Cocoa Touch框架中找到这种模式; UIPickerViewDelegate
,UIImagePickerControllerDelegate
和UINavigationControllerDelegate
,只是几个例子.
你应该遵循标准模式,除非你有令人信服的理由不这样做.遵循惯例将使其他人(以及将来您)更容易理解您的代码.