id确认了一个协议,但执行在哪里



这可能是一个幼稚的问题,但我感觉有点迷路。我在苹果文档中阅读了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; 

最新更新