繁体   English   中英

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

[英]What exactly are protocols and delegates and how are they used in IOS?

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

编辑:

据我所知,

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

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

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

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

如果我错了,请纠正我。

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

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

您以这种方式指定协议:

@protocol MyProtocol <NSObject>

- (void)aRequiredMethod;

@required
- (void)anotherRequiredMethod;

@optional
- (void)anOptionalMethod;

@end

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

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

@interface MyClass <MyProtocol>

@end

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

@property (nonatomic, weak) id<MyProtocol> delegate;

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

[self.delegate aRequiredMethod];

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

[self.delegate conformsToProtocol:@protocol(MyProtocol)]

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

[self.delegate respondsToSelector:@selector(anOptionalMethod)]

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

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

id<MyProtocol> instanceOfClassThatImplementsMyProtocol;

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

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

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

编辑:

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

@property(nonatomic, assign) id<UITextFieldDelegate> delegate

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

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

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

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

@interface car : NSObject

@property (nonatomic) id engine;

@end

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

[_engine start];

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

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

@property (nonatomic) id <engineDelegate> engine;

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

@protocol engineDelegate 
 - (void) start;
@optional
 - (double) fuelLevel;
@end

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

@interface timeWarpDrive : NSObject <engineDelegate>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM