如何在Objective-C中引用协议?
我知道协议的指令是@protocol就像@选择器一样,但是引用一个协议的“类型”是什么(比如@Selector的SEL)?在MacOSX堆栈中,它是协议*?如何在Objective-C中引用协议?
可引用它作为:
id<TheNameOfTheProtocol> aVariableToThatProtocol;
或者,如果一个消息想要一个(Protocol *)
对象:
[myObject conformsToProtocol:@protocol(TheNameOfTheProtocol)];
id <YourProtocol> delegate
(其被用于引用协议)?
我所提到的苹果的官方DOC,并发现了一个简单的例子来参照其它协议在一个协议:
#import "B.h"
@protocol B; // To break the recursive cycle, you must use the @protocol directive to make a forward reference to the needed protocol instead of importing the interface file where the protocol is defined
@protocol A
- foo:(id <B>)anObject;
@end
其中协议B可以声明如下:
#import "A.h"
@protocol B
- bar:(id <A>)anObject;
@end
请注意,以这种方式使用@protocol指令只是通知编译器B是稍后定义的协议。它不会导入定义协议B的接口文件。你想
而且我这里还有更多的事情了解:
在很多方面,协议类似于类定义。它们都声明方法,并且在运行时它们都由对象来表示,它们由Class的实例和Protocol的实例来表示。像类对象一样,协议对象是从源代码中的定义和声明中自动创建的,并被运行时系统使用。 它们没有在程序源代码中分配和初始化。
源代码可以是指协议对象使用@protocol()指令声明协议-the相同的指令,所不同的是在这里它具有一组拖尾括号。括号包围协议名称:
Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport);
这是源代码可以变出协议对象的唯一途径。与类名不同,协议名称不指定对象,除了@protocol()内部。
而且更重要的是,该可以通过发送一个conformsToProtocol:
消息来检查对象是否符合协议:
if (! [receiver conformsToProtocol:@protocol(MyXMLSupport)] ) {
// Object does not conform to MyXMLSupport protocol
// If you are expecting receiver to implement methods declared in the
// MyXMLSupport protocol, this is probably an error
}
的conformsToProtocol:测试样respondsToSelector:测试一个单一的方法,除了它测试协议是否被采用(并且大概所有的它声明的方法被实现),而不仅仅是一个特定的方法是否被实现。因为它检查协议中的所有方法,所以conformsToProtocol:可以比respondsToSelector更有效:。
的conformsToProtocol:测试也是像isKindOfClass:测试,不同之处在于它测试用于基于协议,而不是基于继承层次一个类型的类型。
这是一样的OS X:
Protocol * p = objc_getProtocol("UITableViewDataSource");
它宣布<objc/runtime.h>
:
typedef struct objc_object Protocol;
只是好奇,有什么理由的协议 “类型” 必须用“ID使用?”从C#背景来看,由于您只是将其声明类似于类引用(即IProtocol协议;),所以将接口引用可视化会更容易一些。 – 5StringRyan 2012-01-06 17:43:07
@ 5StringRyan我不知道推理,但是'id'类型是任何对象的一般类型,即使它不是NSObject。这种语法的一个优点是它允许多种协议。你可以按照'id'的方式做一些事情来表达对象符合两种协议。或者,如果您的协议不符合NSObject,但您引用的类实例可以执行以下操作:'id '。 –
2012-01-06 17:52:56
@ 5StringRyan该类型确实*不*必须是'id'。例如:'NSArray * var = [NSArray array];'有时是合法的。你也可以写'NSArray * var = [NSArray array];'sooo ...这当然是注入某种类型安全的好方法。 (这些例子很愚蠢 - 它们只是演示语法) –
justin
2012-01-06 18:06:16