这可能是一个幼稚的问题,但我感觉有点迷路。我在苹果文档中阅读了iOS开发者关于协议的指南,但不是很有意义。让我用尽可能简短的方式解释我的困境。
假设我有如下协议
@protocol MyProtocol<NSObject>
- (void)someMessage;
@end
然后在我的代码中,我像这样声明了一个变量,
id<MyProtocol> someVar;
到目前为止一切顺利,但是someVar
是一个id类型,那么我们将在哪里实现-(void) someMessage;
呢?
注:我有知识,如,实现定义接口的函数应该在实现它的类中接口。这种理解是从Java中得来的,而且在Java中是非常的显然知道哪个对象来自哪个类和哪个接口这个类实现。但是上面的Objective C方式让我很困惑:(.
当你写:
id<MyProtocol> someVar
你只是说"someVar"将是任何类的对象,但是这个类将尊重协议MyProtocol。
所以在你的代码中会有一些点会实例化一些变量。此时,一些var将被关联到一个类。这个类必须满足MyObject协议。请注意,编译器将尽其所能在问题的情况下警告你,例如,如果你将这个对象强制转换为一些不尊重协议的类,例如,假设你的协议定义了一个名为"protocolMethod"的方法,那么:
[(NSArray *)someVar protocolMethod]
将生成一个编译器警告("NSArray可能不响应protocolMethod")。
当然,你永远不会受到运行时错误的保护:所以如果在运行时你创建了一些不满足协议的类的var,那么任何对协议方法的调用都会引发异常。
简而言之,Objective-C协议在概念和代码方面与Java接口大致相似。
如果你将一个Java变量声明为接口类型,这意味着它可以接受实现该接口的任何对象。在Objective-C中,id
变量表示任何指针类型,因此id<MyProtocol>
表示指向采用MyProtocol
的对象的任何指针,在这个意义上类似于Java接口类型声明。
在Java中,您在类中实现接口方法,并声明该类来实现接口。类似地,在Objective-C中,你在一个类中实现一个协议方法,并让那个类采用该协议。
下面是Java和Objective-C之间的代码比较(同样,这只是两个类似概念的松散比较):
Java
public interface MyInterface {
void someMethod();
}
public class MyClass implements MyInterface {
public void someMethod() {
System.out.println("Some method was called");
}
}
public class Main {
public static void main(String[] args) {
// Any class that implements MyInterface can be
// assigned to this variable
MyInterface someVar = new MyClass();
someVar.someMethod();
}
}
objective - c @protocol MyProtocol <NSObject>
- (void)someMessage;
@end
@interface MyClass : NSObject <MyProtocol>
- (void)someMessage;
@end
@implementation MyClass
- (void)someMessage {
NSLog(@"Some message was sent");
}
@end
int main(int argc, const char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Any class that adopts MyProtocol can be
// assigned to this variable
id<MyProtocol> someVar = [[MyClass alloc] init];
[someVar someMessage];
[someVar release];
[pool drain];
return 0;
}
您需要实现一个类来实现协议中的方法例如
@interface MyObject: NSObject <NyProtocol>
- (void)someMessage;
@end
和
@implementation MyObject
-(void)someMessage()
{
printf(@"a message"); ...
}
@end
然后用这个作为
someVar = [MyObiect alloc]......
你也可以将这个方法实现为NSObject上的一个类别,这样所有的类都可以使用。
参见采用apple Objective C概念文档中的协议
我在NSObject上写了一个名为StrictProtocols的类别来解决这个"问题"。它实现了以下方法…
/* "non" doesn't implement ANY of the declared methods! */
[non implementsProtocol:proto]; -> NO;
[non implementsFullProtocol:proto]; -> NO;
/* "semi" doesn't implement the @optional methods */
[semi implementsProtocol:proto]; -> YES;
[semi implementsFullProtocol:proto]; -> NO;
/* "strict" implements ALL, ie the @optional, @required, and the "unspecified" methods */
[strict implementsProtocol:proto]; -> YES;
[strict implementsFullProtocol:proto]; -> YES;