协议和代理究竟是什么以及它们在IOS中的使用方式?

Ole*_*siy 20 delegates protocols ios

我对委托和协议的概念感到困惑.它们是否等同于Java中的接口和适配器类?他们是如何工作的?到目前为止,我所阅读的资源都没有帮助."委托是一种简单而强大的模式,其中程序中的一个对象代表另一个对象或与另一个对象协调.委托对象保留对另一个对象的引用 - 委托 - 并在适当的时候发送消息它." 我不知道这是什么意思.有人可以解释一下它们是什么并给出一个简单的例子吗?提前致谢!

编辑:

据我所知,

1)委托实现协议(接口的另一个名称)

2)对象注册委托(实现协议)

3)对象可以在委托上调用协议方法

因此,委托将对象与协议连接.

如果我错了,请纠正我.

我还是不明白为什么对象本身无法实现协议?它可能会变得如此简单!

Gia*_*one 44

协议是一种指定一组希望类实现的方法的方法,如果它想要使用其中一个类.像UITableViewDelegate和UITableViewDataSource这样的代理和数据源确实是协议.

您以这种方式指定协议:

@protocol MyProtocol <NSObject>

- (void)aRequiredMethod;

@required
- (void)anotherRequiredMethod;

@optional
- (void)anOptionalMethod;

@end
Run Code Online (Sandbox Code Playgroud)

在@required之后或在任何其他说明符之前声明的方法以及想要使用您的协议的类需要实现所有这些.您还可以通过在@optional说明​​符后声明它们来声明一些可选方法.

然后,您可以在类的接口中指定类"符合"协议(实现所需的方法):

@interface MyClass <MyProtocol>

@end
Run Code Online (Sandbox Code Playgroud)

您通常使用属性保持对符合协议的对象的引用.例如,要跟踪委托:

@property (nonatomic, weak) id<MyProtocol> delegate;
Run Code Online (Sandbox Code Playgroud)

此时,在您的代码中,您只需要调用要在其保持引用的对象上调用的方法,并实现您的协议,就像使用任何其他方法一样:

[self.delegate aRequiredMethod];
Run Code Online (Sandbox Code Playgroud)

检查对象是否符合您可以调用的协议

[self.delegate conformsToProtocol:@protocol(MyProtocol)]
Run Code Online (Sandbox Code Playgroud)

检查对象是否实现了可以调用的方法

[self.delegate respondsToSelector:@selector(anOptionalMethod)]
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看Apple的使用协议指南.


iPh*_*er. 10

(@protocol syntax in Objective-C)使用声明的协议声明了一组方法,即"采用"(声明它将使用此协议)的类将实现.这意味着您可以在代码中指定"只要它实现特定协议,您就不关心使用哪个类".这可以在Objective-C中完成,如下所示:

id<MyProtocol> instanceOfClassThatImplementsMyProtocol;
Run Code Online (Sandbox Code Playgroud)

如果在代码中说明了这一点,则可以在变量中使用"符合"协议MyProtocol的任何类instanceOfClassThatImplementsMyProtocol.这意味着使用此变量的代码知道它可以使用MyProtocol中定义的任何方法与此特定变量,无论它是什么类.这是避免继承设计模式和避免紧耦合的好方法.

代表使用协议的语言功能.委托设计模式是一种设计代码以在必要时使用协议的方法.在Cocoa框架中,委托设计模式用于指定符合特定协议的类的实例.此特定协议指定委托类应在给定事件中执行特定操作的方法.使用委托的类知道它的委托符合协议,因此它知道它可以在给定时间调用已实现的方法.这种设计模式是解耦类的好方法,因为它使得将一个委托实例交换为另一个委托实例变得非常容易 - 程序员必须做的就是确保替换实例或类符合必要的协议(即

协议和委托不仅限于Objective-C和Mac/iOS开发,而Objective-C语言和Apple框架大量使用这种令人敬畏的语言特性和设计模式.

编辑:

请找到这个例子.在UIKit frameworkCocoa Touch中,有一个UITextFieldDelegate协议.该协议定义了一系列方法,这些方法UITextField应该实现一个实例的委托.换句话说,如果要将委托分配给UITextField(使用委托属性),则最好确保此类符合UITextFieldDelegate.实际上,因为delegate属性UITextField定义为:

@property(nonatomic, assign) id<UITextFieldDelegate> delegate
Run Code Online (Sandbox Code Playgroud)

然后,如果为其分配一个未实现协议的类,编译器将发出警告.这非常有用.你必须声明一个类实现了一个协议,并且说它确实存在,你让其他类知道它们可以以特定的方式与你的类进行交互.因此,如果您将一个实例分配给MyTextFieldDelegateClass委托属性UITextField,则UITextField知道它可以调用您的某些特定方法(与文本输入,选择等相关)MyTextFieldDelegateClass.它知道这一点,因为MyTextFieldDelegateClass已经说它将实现UITextFieldDelegate协议.

最终,这一切都会为您的项目代码带来更大的灵活性和适应性,我相信您在使用这项技术后很快就会意识到这一点!:)


Chr*_*ris 9

在它最简单的形式中,委托是一个从另一个对象接收消息的对象.你一直这样做.

所以说你有一个带引擎的汽车对象.

@interface car : NSObject

@property (nonatomic) id engine;

@end
Run Code Online (Sandbox Code Playgroud)

因此可以将启动消息转发给引擎.

[_engine start];
Run Code Online (Sandbox Code Playgroud)

引擎充当委托,你只是传递一个消息.

协议使它更正式,Xcode将检查您是否符合所需或可选方法.

@property (nonatomic) id <engineDelegate> engine;
Run Code Online (Sandbox Code Playgroud)

说引擎对象必须包含函数start,因为在它要求的协议定义中.

@protocol engineDelegate 
 - (void) start;
@optional
 - (double) fuelLevel;
@end
Run Code Online (Sandbox Code Playgroud)

为什么代表和协议如此酷?好吧,因为发动机可以是你可以在运行时使用的任何数量的不同发动机,它可以是喷气发动机,内燃发动机,相位调制发动机无关紧要,只要它符合协议.并且通过将委托添加到类接口来告诉Xcode它是否符合要求.

@interface timeWarpDrive : NSObject <engineDelegate>
Run Code Online (Sandbox Code Playgroud)

  • 如果您通过显示每个文件的文件名/完整代码示例详细说明您的代码示例,这个答案对初学者会更有帮助. (6认同)