目前,我正在自学iOS编程,我发现真正难以理解的一个概念是委托。它是什么?为什么以及如何使用?有什么好处?我正在阅读的书中的技术性著作很难理解。
目前,我正在自学iOS编程,我发现真正难以理解的一个概念是委托。它是什么?为什么以及如何使用?有什么好处?我正在阅读的书中的技术性著作很难理解。
Answers:
要了解delegates
,您必须了解protocols
。
A protocol
就像服务合同。当一个对象(通常是UIViewController
子类,但并非总是)签署该合同时,它说的是“我有兴趣提供逻辑来支持您发送给我的消息”。这类似于NSNotificationCenter
在签署兴趣级别方面,区别在于使用委派的对象一次只能拥有一个delegate
,而多个对象可以同一对象进行签名NSNotification
。
苹果公司普遍使用授权。不过,您越来越多地看到Apple将其许多API移至blocks
,与callbacks
其他语言类似。
话虽如此,即使我认为委托本身就是一种设计模式,委托也有助于维护MVC。它有助于将模型与控制器分离。例如在约翰·卡特赖特(John Cartwright)的示例中,a UITableView
知道如何显示行和节。UITableViewCells
由于性能原因,它知道如何重用。它知道所有其他UIScrollView
已知的东西。但是它不知道显示哪些单元格。它不知道用什么填充这些单元格。它不知道要为给定重用哪些单元格NSIndexPath
。无论如何,这确实应该是控制器的工作。委托允许表视图将这种非视图逻辑卸载到应该承担该责任的对象上。
不仅如此,您在对象的整个生命周期中都不会被锁定在一个委托中。您可以轻松地为给定拥有多个数据源,UITableView
并根据需要在运行时切换它们。
因此,一方面,委派对于将数据提供给对象并响应对象的交互非常有用。你会看到它在很多UIKit类,这样的的UITableView
,UIPickerView
,UICollectionView
,等。
但是,当您要在对象之间传递信息时,委托也非常有用。您可以非常轻松地创建自己的协议并注册自己的对象以遵循它们。此外,协议方法是@required
默认设置,但是您可以指定一些方法@optional
。如果需要,可以为您提供一些不错的灵活性。假设您有一个父视图控制器和一个子视图控制器。也许您正在使用新的Containment API来执行此操作。通常,如果您需要将信息从父级传递给子级,则可以使用属性来实现。做完了 但是,如果您需要将信息从孩子传回给父母,该怎么办?也许孩子有所改变,您需要通知父母。当然,您可以对某些值进行一些KVO。但是也许您想知道何时按下按钮。只需在子视图控制器中创建一个新协议
@protocol MyChildDelegate
- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController;
@end
@interface MyChildViewController : UIViewController
@property (weak, nonatomic) id <MyChildDelegate> delegate;
@end
在MyChildViewController中,点击按钮时,只需检查委托是否响应委托消息(如果是必需的,并且委托未实现该方法,则会崩溃。@optional
如果需要,可以创建该方法)并发送它:
- (IBAction)someButtonTapped:(id)sender {
if ([self.delegate respondsToSelector:@selector(buttonWasTappedInChild:)]) {
[self.delegate buttonWasTappedInChild:self];
}
}
然后将MyChildViewController的委托设置为self
并- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController
在父视图控制器中实现。繁荣!您有从孩子传到父母的信息。这两个对象之间的关系甚至不必像父/子一样紧密。这是一项服务合同,只要签约的对象通过实施所需的方法来维持其讨价还价的条件,您就可以做到!
注意:委托应该是弱属性/分配属性,否则,您将进入一个保留周期,在该周期中无法释放任何对象。
希望这可以帮助!