id 确认了一个协议,但是在哪里实现呢?

发布于 2024-12-08 07:08:21 字数 773 浏览 3 评论 0原文

这可能是一个天真的问题,但我感觉有点迷失。我阅读了有关协议的 iOS 开发人员指南 Apple 文档,但不太有意义。让我以最简短的方式解释我的困境。

可以说我有如下协议,

@protocol MyProtocol<NSObject>
- (void)someMessage;
@end

并且在我的代码中我声明了一个这样的变量,

id<MyProtocol> someVar;

到目前为止一切顺利,但是 someVar 是一个 id 类型,所以我们将在其中实现 -(void ) someMessage;?


注意:我拥有以下知识:定义的实现 接口的函数应该位于实现该接口的类中 界面。这个理解是来自Java所以,并且在Java中这是非常 明显知道哪个对象来自哪个类以及哪个接口 该类实现。但上面的 Objective C 方式让我很困惑:(。


It's probably a naive question, But I am feeling kinda lost. I read iOS developer guide about protocols at Apple Documentation, But didn't quite make sense. Let me explain my dilemma in a shortest possible way.

Lets say I have protocol as below,

@protocol MyProtocol<NSObject>
- (void)someMessage;
@end

And than in my code I am declaring a variable like this,

id<MyProtocol> someVar;

So far so good, But someVar is an id type so where we will implement -(void) someMessage;?


NOTE: I have knowledge such as, Implementation of defined
functions of interface should be inside a Class which implements that
interface. This understanding is from Java so, and in Java it is very
apparent to know which object is from which class and what interface
that class implements. But above Objective C way just confused me :(.


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

长梦不多时 2024-12-15 07:08:21

当您编写:

id<MyProtocol> someVar

您只是声明“someVar”将是任何类的对象,但该类将遵守协议 MyProtocol。

因此,您的代码中会有某个点会实例化 someVar。此时 someVar 将关联到一个类。该类必须满足 MyObject 协议。
请注意,编译器将尽力在出现问题时向您发出警告,例如,如果您将此对象强制转换为某个不遵守协议的类,例如假设您的协议定义了一个名为“protocolMethod”的方法,那么:

[(NSArray *)someVar protocolMethod]

将生成一个编译器警告(“NSArray 可能不会响应协议方法”)。

当然,您永远不会受到运行时错误的保护:因此,如果在运行时您创建的 someVar 属于不满足协议的类,那么对协议方法的任何调用都会引发异常。

When you write:

id<MyProtocol> someVar

you're simply stating that "someVar" will be an object of any class, but this class will respect the protocol MyProtocol.

So there will be some point in your code that will instantiate someVar. At this point someVar will be associated to a class. This class must satisfy the MyObject protocol.
Note that the compiler will do its best to warn you in case of issues, e.g. if you cast this object to some class that doesn't respect the protocol, e.g. suppose your protocol defines a method called "protocolMethod" then:

[(NSArray *)someVar protocolMethod]

will generate a compiler warning ("NSArray may not respond to protocolMethod").

Of course you will never be protected from runtime errors: so if at runtime you create someVar to be of a class that doesn't satisfy the protocol, then any calls to the protocol methods will raise an exception.

琉璃梦幻 2024-12-15 07:08:21

简而言之,Objective-C 协议在概念和代码方面与 Java 接口大致相似。

如果将 Java 变量声明为接口类型,则意味着它可以接受实现该接口的任何对象。在 Objective-C 中,id 变量表示任何指针类型,因此 id 表示指向采用 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;
}

Objective-C protocols are loosely similar to Java interfaces in terms of concepts and in code, to put it simply.

If you declare a Java variable to be of an interface type, it means it can accept any object that implements that interface. In Objective-C, an id variable means any pointer type, so id<MyProtocol> means any pointer to an object that adopts MyProtocol, and is similar to a Java interface type declaration in that sense.

In Java, you implement an interface method in a class, and declare that class to implement the interface. Similarly, in Objective-C, you implement a protocol method in a class, and have that class adopt the protocol.

Here's a code comparison between Java and Objective-C (again it's just a loose comparison of two similar concepts):

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;
}
软的没边 2024-12-15 07:08:21

您需要实现一个类来实现协议中的方法
例如

@interface MyObject: NSObject <NyProtocol>
- (void)someMessage;
@end

@implementation MyObject
-(void)someMessage()
{
  printf(@"a message");  ...
}
@end

然后使用它作为

someVar = [MyObiect alloc]......

您还可以将该方法实现为 NSObject 上的类别,以便所有类都可用。

请参阅采用 Apple 的协议 Objective C 概念文档

You need to implement a class that implements the methods in the Protocol
e.g.

@interface MyObject: NSObject <NyProtocol>
- (void)someMessage;
@end

and

@implementation MyObject
-(void)someMessage()
{
  printf(@"a message");  ...
}
@end

And then use this as

someVar = [MyObiect alloc]......

You could also implement the method as a category on NSObject so available to all classes.

See Adopting a Protocol from Apples Objective C concept document

夏夜暖风 2024-12-15 07:08:21

我在 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; 

I wrote a category on NSObject - called StrictProtocols - that solves this "problem". It implements the following methods...

/* "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; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文