协议和委托到底是什么,它们在 IOS 中是如何使用的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17192287/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What exactly are protocols and delegates and how are they used in IOS?
提问by Oleksiy
I'm really confused about the concept of delegates and protocols. Are they equivalent of interfaces and adapter classes in Java? How do they work? None of the resources I've read were helpful so far. "Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it." I have no idea what this means. Can someone please explain what they are and give a simple example? Thanks in advance!
我真的对委托和协议的概念感到困惑。它们是否等同于 Java 中的接口和适配器类?它们是如何工作的?到目前为止,我读过的所有资源都没有帮助。“委托是一种简单而强大的模式,其中程序中的一个对象代表另一个对象或与另一个对象协同工作。委托对象保持对另一个对象(即委托)的引用,并在适当的时间发送消息到它。” 我不知道这是什么意思。有人可以解释一下它们是什么并举一个简单的例子吗?提前致谢!
EDIT:
编辑:
As far as I now understand,
据我现在了解,
1) delegates implement protocols (another name for interfaces)
1)委托实现协议(接口的另一个名称)
2) object registers a delegate (that implements a protocol)
2)对象注册一个委托(实现一个协议)
3) object can call protocol methods on the delegate
3)对象可以调用委托上的协议方法
Therefore, a delegate is connecting the object with the protocol.
因此,委托将对象与协议连接起来。
Please correct me if I'm wrong.
如果我错了,请纠正我。
I still don't understand why the object itself can't implement a protocol? It could've been so much easier!
我还是不明白为什么对象本身不能实现协议?本来可以简单得多!
回答by Gianluca Tranchedone
Protocols are a way to specify a set of methods you want a class to implement if it wants to work with one of your classes. Delegates and Data Sources like UITableViewDelegate and UITableViewDataSource are protocols indeed.
协议是一种指定您希望类实现的一组方法的方法,如果它想与您的一个类一起工作。像 UITableViewDelegate 和 UITableViewDataSource 这样的委托和数据源确实是协议。
You specify a protocol this way:
您可以通过以下方式指定协议:
@protocol MyProtocol <NSObject>
- (void)aRequiredMethod;
@required
- (void)anotherRequiredMethod;
@optional
- (void)anOptionalMethod;
@end
Methods declared after the @required or before any other specifier are required and the classes that want to use your protocol need to implement all of them. You can also declare some optional methods by declaring them after the @optional specifier.
在@required 之后或任何其他说明符之前声明的方法是必需的,并且想要使用您的协议的类需要实现所有这些方法。您还可以通过在@optional 说明符之后声明一些可选方法来声明它们。
You then can specify that a class "conforms" to a protocol (implements the required methods) in the interface of the class:
然后,您可以在类的接口中指定类“符合”协议(实现所需的方法):
@interface MyClass <MyProtocol>
@end
You usually keep a reference to an object conforming to a protocol using a property. For example, to keep track of a delegate:
您通常使用属性保留对符合协议的对象的引用。例如,要跟踪委托:
@property (nonatomic, weak) id<MyProtocol> delegate;
At this point, in your code, you just have to call the method you want to call on the object that you're keeping reference of and that implements your protocol as you would with any other method:
在这一点上,在您的代码中,您只需要调用您要调用的方法,该方法是您保持引用的对象,并像使用任何其他方法一样实现您的协议:
[self.delegate aRequiredMethod];
To check whether an object conforms to a protocol you can call
要检查对象是否符合您可以调用的协议
[self.delegate conformsToProtocol:@protocol(MyProtocol)]
To check whether an object implements a method you can call
要检查对象是否实现了可以调用的方法
[self.delegate respondsToSelector:@selector(anOptionalMethod)]
For more information, check the Apple's guide Working With Protocols.
有关更多信息,请查看 Apple 的使用协议指南。
回答by iPhone developer.
A protocol which declared with the (@protocol syntax in Objective-C)
is used the declare a set of methods that a class that "adopts" (declares that it will use this protocol) will implement. This means that you can specify in your code that, "you don't care which class is used so long as it implements a particular protocol". This can be done in Objective-C as follows:
(@protocol syntax in Objective-C)
使用 声明的协议用于声明一组“采用”(声明它将使用此协议)的类将实现的方法。这意味着您可以在代码中指定“只要实现特定协议,您就不必关心使用哪个类”。这可以在 Objective-C 中完成,如下所示:
id<MyProtocol> instanceOfClassThatImplementsMyProtocol;
If you state this in your code, then any class that "conforms" to the protocol MyProtocol can be used in the variable instanceOfClassThatImplementsMyProtocol
. This means that the code that uses this variable knows that it can use whichever methods are defined in MyProtocol with this particular variable, regardless of what class it is. This is a great way of avoiding the inheritance design pattern, and avoids tight coupling.
如果您在代码中声明了这一点,那么任何“符合”协议 MyProtocol 的类都可以在变量中使用instanceOfClassThatImplementsMyProtocol
。这意味着使用这个变量的代码知道它可以使用 MyProtocol 中定义的任何方法来定义这个特定变量,而不管它是什么类。这是避免继承设计模式和避免紧耦合的好方法。
Delegates are a use of the language feature of protocols. The delegation design pattern is a way of designing your code to use protocols where necessary. In the Cocoa frameworks, the delegate design pattern is used to specify an instance of a class which conforms to a particular protocol. This particular protocol specifies methods that the delegate class should implement to perform specific actions at given events. The class that uses the delegate knows that its delegate coforms to the protocol, so it knows that it can call the implemented methods at given times. This design pattern is a great way of decoupling the classes, because it makes it really easy to exchange one delegate instance for another - all the programmer has to do is ensure that the replacement instance or class conforms to the necessary protocol (i.e. it implements the methods specified in the protocol)!
委托是使用协议的语言特性。委托设计模式是一种设计代码以在必要时使用协议的方法。在 Cocoa 框架中,委托设计模式用于指定符合特定协议的类的实例。此特定协议指定委托类应实现的方法,以在给定事件中执行特定操作。使用委托的类知道它的委托符合协议,因此它知道它可以在给定的时间调用已实现的方法。这种设计模式是一种解耦类的好方法,因为它可以很容易地将一个委托实例交换为另一个 - 程序员所要做的就是确保替换实例或类符合必要的协议(即
Protocols and delegates are not restricted only to Objective-C and Mac/iOS development, but the Objective-C language and the Apple frameworks make heavy use of this awesome language feature and design pattern.
协议和委托不仅限于 Objective-C 和 Mac/iOS 开发,而且 Objective-C 语言和 Apple 框架大量使用了这种很棒的语言特性和设计模式。
Edit:
编辑:
Please find this Example. In the UIKit framework
of Cocoa Touch, there is a UITextFieldDelegate
protocol. This protocol defines a series of methods that classes which are delegates of a UITextField
instance should implement. In other words, if you want to assign a delegate to a UITextField
(using the delegate property), you'd better make sure that this class conforms to UITextFieldDelegate
. In fact, because the delegate property of UITextField
is defined as:
请找到这个例子。在UIKit framework
Cocoa Touch 中,有一个UITextFieldDelegate
协议。该协议定义了作为UITextField
实例委托的类应该实现的一系列方法。换句话说,如果你想给 a 分配一个委托UITextField
(使用 delegate 属性),你最好确保这个类符合UITextFieldDelegate
. 实际上,因为的委托属性UITextField
定义为:
@property(nonatomic, assign) id<UITextFieldDelegate> delegate
Then, the compiler will give warnings if you assign a class to it that doesn't implement the protocol. This is really useful. You have to state that a class implements a protocol, and in saying that it does, you're letting other classes know that they can interact in a particular way with your class. So, if you assign an instance of MyTextFieldDelegateClass
to the delegate property of UITextField
, the UITextField
knows that it can call some particular methods (related to text entry, selection etc.) of your MyTextFieldDelegateClass
. It knows this because MyTextFieldDelegateClass
has said that it will implement the UITextFieldDelegate
protocol.
然后,如果您为它分配一个未实现协议的类,编译器将发出警告。这真的很有用。你必须声明一个类实现了一个协议,并且说它实现了,你让其他类知道它们可以以特定的方式与你的类交互。因此,如果您将 的实例分配MyTextFieldDelegateClass
给 的委托属性UITextField
,则UITextField
知道它可以调用您的MyTextFieldDelegateClass
. 它知道这一点,因为MyTextFieldDelegateClass
已经说过它将实施该UITextFieldDelegate
协议。
Ultimately, this all leads to much greater flexibility and adaptability in your project's code, which I'm sure you'll soon realise after using this technology! :)
最终,这一切都会为您的项目代码带来更大的灵活性和适应性,我相信您在使用这项技术后很快就会意识到这一点!:)
回答by Chris
In it's simplest form a delegate is an object which receives messages from another object. And you do it all the time.
在最简单的形式中,委托是从另一个对象接收消息的对象。而你一直都在这样做。
So say you had car object with an engine.
所以说你有一个带引擎的汽车对象。
@interface car : NSObject
@property (nonatomic) id engine;
@end
So could forward a start message to the engine.
因此可以将启动消息转发给引擎。
[_engine start];
The engine is acting as a delegate, you're just passing it a message.
引擎充当代理,您只是向它传递消息。
Protocols make it more formal, and Xcode will check that you are conforming to the required or optional methods.
协议使它更正式,Xcode 将检查您是否符合必需或可选的方法。
@property (nonatomic) id <engineDelegate> engine;
says that the engine object MUST contain the function start because in the the protocol definition it asked for it.
说引擎对象必须包含函数 start 因为在它要求的协议定义中。
@protocol engineDelegate
- (void) start;
@optional
- (double) fuelLevel;
@end
Why are delegates and protocols so cool? Well because the engine could be any number of different engines which you could use at runtime, it could be a jet engine, a combustion engine, a phasing modulating engine it doesn't matter, as long as it conforms to the protocol. And you tell Xcode that it does conform by adding the delegate to the class interface.
为什么代表和协议如此酷?好吧,因为引擎可以是您可以在运行时使用的任意数量的不同引擎,它可以是喷气发动机、内燃机、相位调制引擎,只要符合协议,就没有关系。并且您通过将委托添加到类接口来告诉 Xcode 它确实符合。
@interface timeWarpDrive : NSObject <engineDelegate>