在Objective-C中,对委托(Delegates)有点困惑。
Delegates是Objective-C中的一种概念,而不是语言特性。UITableView是一个很好的例子来理解delegates。UITableView有一个delegate和dataSource,它们都是接收者的辅助对象。tableView不会直接处理例如用户点击某行时的事件,而是告诉它的delegate:“嘿!我被点击了这一行和这个section,你来处理吧!”。通常,delegate是一个Controller,它实现了正确的方法。因此,tableView会发送如下的消息(在检查delegate是否有该方法的定义后):
[delegate tableView:self didSelectRowAtIndexPath:indexPath];
由于你的Controller是tableView的delegate,并且实现了该方法,它决定了要做什么。当方法完成后(在这种情况下应该只返回void),执行会继续在tableView上进行。
Delegates是一种概念,而不是Objective-C的语言特性。UITableView的delegate成员就像其他对象一样。尽管delegate通常不会被retain,而是被赋值(以避免retain循环)。
一旦你掌握了delegates,它们非常方便。建议通过TableViews等示例进行练习(就像之前提到的NSTableView一样,它的工作方式相似,只是使用了不同的方法)。
所以,delegate是一个对象,当对象自身发生某些事情时,它会调用delegate的某个方法。根据对象发生的具体情况,它会调用delegate类中的特定方法。是这样吗?创建一个delegate类有正确的方法吗,还是它只是另一个普通的类,其他类恰好调用它的方法?
从技术上讲,delegate是一个对象。你可以有五十个实现一些delegate方法的对象实例,但只有设置为delegate的实例才会调用它的方法。创建delegate的正确方法是定义一个protocol,该protocol定义了必须/可以被实现的一组方法。
你说得对,delegate可以是任何类型的对象。尽管通常它将是一个符合某个protocol的对象。如果一个对象符合给定的protocol,它基本上意味着“我承诺我已经实现了给定protocol中要求的所有内容”。这样,当一个对象向delegate发送消息时,它们可以确信delegate知道该做什么。
还有一件事我要确保我理解正确...当点击一个cell时,它使用一个delegate对象的实例并发送一个消息给它。delegate类有一个方法来处理接收到的内容,根据接收到的信息,该方法执行某些操作,是这样吗?
正确。在我的table示例中,当选择了cell,table会准备一个叫做indexPath的对象(表示选择的是哪一行)然后将其传递给delegate中的上述方法。所以,delegate可以简单地是一个NSObject子类,它实现了上述方法。当table调用它时,使用indexPath,我们的delegate执行方法,使用indexPath做一些操作,然后返回void。Delegate方法不一定要返回void,但这个方法是这样的。有些方法返回bool值,有些返回float值(例如cell的高度)等等。
数据源不是delegate。
正确,我会澄清这一点。
在Objective-C中,委托(Delegate)用于解决当用户点击按钮时,如何知道调用哪个对象的哪个方法的问题。为了使一个类成为委托,我们需要在声明中将其声明为委托。比如,在上面的例子中,假设有一个ApplicationController对象来控制应用程序的流程。在声明中,我们会写上ApplicationController : NSObject <UIAlertViewDelegate>
,这告诉编译器ApplicationController将实现UIAlertViewDelegate协议中的一些方法。我们在文档中查找该协议,并看到了一系列方法。由于我们想要在用户按下按钮时执行一些操作,我们找到了alertView:clickedButtonAtIndex:
方法,它会在用户点击警告框上的按钮时发送给委托对象。如果我们在ApplicationController中实现了一个名为alertView:clickedButtonAtIndex
的方法,并创建一个ApplicationController对象,然后将该对象设置为我们显示的警告框的委托,那么一切都设置好了。当有人按下警告框上的按钮时,alertView:clickedButtonAtIndex
方法将会被调用,传入警告框和按钮的索引。这样,我们就可以根据这些信息做任何我们想做的事情。一个简单的情况可以使用一个switch语句来处理按钮的索引,比如:
if( buttonIndex == 0 ) { _myString = @"Pressed the button"; } else { _myString = @"Pressed the other button"; }
。Objective-C的参考文档非常好,所有的委托协议都相当直观易懂。
至于at符号的含义,这取决于你指的是哪一个。在Objective-C中,可以通过使用@"string here"的方式在代码中定义字符串,这是Objective-C的一种语法特性。而在类声明中,@表示一个类的声明。Objective-C中有很多以@开头的特性,这是为了确保与C/C++中的标识符不产生混淆。因为在C/C++中,@符号从未被用作标识符。这样做可以确保Objective-C的开发人员不会混淆是否可以将某个东西归为C/C++或Objective-C的范畴。
在Objective-C中,出现了关于代理(Delegates)的一些困惑。代理可以被看作是依赖关系的反转。在大多数框架中,客户端会将所需的依赖项注入到实例中,通常是通过构造函数或者设置器来实现的。而Cocoa则相反,实例会在需要的时候请求数据。
代理方法主要有四种类型:
1. 有条件的前置方法 - 表示某个事件即将发生,但是代理有可能会终止。方法名中总是包含"Should"关键字。
示例:searchBarShouldEndEditing:。
2. 无条件的前置方法 - 表示某个事件即将发生。方法名中总是包含"Will"关键字。
示例:applicationWillTerminate:。
3. 无条件的后置方法 - 表示某个事件已经发生。方法名中总是包含"Did"关键字。
示例:applicationDidFinishLaunching:。
4. 定制方法 - 请求一些用于自定义功能的信息。方法名中包含所需的信息。
示例:tableView:viewForHeaderInSection:。
所有的代理方法都会将发送者作为其中一个参数。任何代理方法都可以有一个返回值,用来改变发送者的行为方式。
解决这个问题的最佳方法是理解代理的概念,以及各种代理方法的不同类型和用途。通过仔细阅读和理解代码示例,可以更好地理解代理的工作原理和用法。
代理在Objective-C中扮演着重要的角色,它可以帮助实现模块化和松耦合的设计,提供了一种灵活的方式来处理对象之间的通信和交互。