Xcode iOS项目中的delegate到底是什么作用?

28

我刚学习iPhone应用程序开发,但是我很难理解什么是代理(delegate)?有人能举例说明它的作用以及其重要性吗?谢谢任何帮助!


请查看:https://dev59.com/-FrUa4cB1Zd3GeqPjmzY 并记得在发布前搜索! :) - Luke
委托方面还有其他问题吗?回答讲得通吗? - bryanmac
请参见链接 - HDdeveloper
3个回答

41

这是一个概念性的关键概念,因此在了解技术细节之前,理解如何思考它非常重要。简而言之,委托是一个回调。

使用委托的两种主要情况:

  1. 类或控件想要抽象出如何完成工作(例如检索数据)的详细信息。
  2. 允许其他人将代码挂接到管道中。

例子:

UITableView - 表视图只是一个知道如何呈现单元格列表的控件。它处理所有繁重的呈现、滚动等工作... 但是,它不知道如何加载您的数据。所以你实现一个数据源委托,它有方法来获取给定行的单元格数据等.. 这让你很容易就可以使用控件并为你的数据插入具体内容。UITableView会为你做所有的事情...只需回答几个特定的问题。委托回答这些几个特定的问题。

文本控件 - 添加文本控件到您的视图中,你就可以在其中输入文字了。但如果您想在用户开始输入或完成输入时执行一些操作怎么办?好吧,文本控件提供了一些方法让你挂接到文本控件的执行管道中。它让文本控件为您完成所有工作,并允许您在需要时插入代码。很多时候,有一种方法可以插入代码来决定某些事情是否被允许。控件会回调并询问,“我能做x吗?”你可以插入代码并影响行为。

如果您正在创建控件或类,您可以创建自己的协议、数据源委托等...这样您的控件就可以专注于所宣传的功能。例如,假设您想创建一个任务控件。你可以:

首先,创建一个合同。嘿,如果你要为我的控件提供数据,这是我要问你的问题。我从那里开始...在这种情况下,我将问你任务数,然后我将让你根据行号给我一个任务。

@protocol XXTaskBoardDelegate <NSObject>
-(NSInteger*)getTaskCount;
-(XXTask*)getTaskForRow:(NSInteger*)rowNumber;
@end
在控件或类中,给消费者提供一种方法来提供实现协议的委托数据源类,以回答控件将要问的问题。此时,控件是一个纯控件。它不知道你如何获取数据。它正在请求实现合同/协议的对象(id)。id
@implementation XXTaskBoard
- (void)setDelegate:(id<XXTaskBoardDelegate>)newDelegate
{
    // the control stores the delegate so it can callback and ask you questions.
}

然后,在委托类中,您需要在头文件中声明实现该正式协议,在实现m文件中提供代码。

@interface AppController : NSObject<XXTaskBoardDelegate> 
{
    //...
}

然后,在实现中实现它。

@implementation AppController
- (NSInteger*)getTaskCount
{
    return [model queryTaskCount];
}

- (XXTask*)getTaskForRow:(NSInteger*)rowNumber
{
    return [[model tasks] getItem:(NSInteger*)rowNumber];
}

10

委托是一个对象,另一个类可以向其传递消息。在实践中,委托类必须符合委托协议。

例如,我们将采取表视图控制器的子类。这是您表视图的代理。首先,通过执行以下操作定义它为表视图代理:

MyTableViewController : UITableViewController <UITableViewDelegate>

这段代码表明 MyTableViewController 类是 UITableViewController 的子类,并符合 UITableViewDelegate 协议。

通过设置 [tableView setDelegate:self](或在 IB 中定义为这样)来将 self 对象传递给 tableview,以便 tableview 向其发送消息。

它发送的主要消息是 didSelectRowAtIndexPath 消息,它告诉您的类用户已经按下了一个表视图单元格。

因此,处理点击事件的对象(table view)会将单元格被点击的消息传递给委托对象(在这种情况下是你的 MyTableViewController 对象)。

委托协议存在的原因是确保委托对象具有处理消息所需的必要方法。委托协议中的方法可以是 @optional 或强制实施的。任何可选的方法都不必定义。在您的 MyTableViewController 类中,didSelectRowAtIndexPath 方法是可选的 - 您不必拥有它。如果表视图找不到该方法,它就不会调用它。

但是,cellForRowAtIndexPath 是必需的,如果没有它,您的应用程序将无法编译。

希望这会对您有所帮助,并且很容易理解。如果您需要更多信息,请告诉我。


3
代理是从某个地方获取回调的一种方式。您将代理(符合协议的对象的指针)传递给某个东西,当它有新数据或发生事件时,该东西会调用代理的方法。
例如,当事件发生时,比如您的应用程序被放入后台或应用程序即将终止时,UIApplication对象将调用您的应用程序代理来通知它。当CLLocationManager有新的GPS位置时,它会调用您的代理来传递新的位置。UITableView调用它们的代理来获取要在表格中显示的UITableViewCells。在iOS中有许多使用代理的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接