Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

id confirms to a protocol, But where will be the implementation?

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 :(.


like image 454
TeaCupApp Avatar asked Oct 03 '11 11:10

TeaCupApp


2 Answers

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.

like image 147
viggio24 Avatar answered Oct 13 '22 01:10

viggio24


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;
}
like image 22
BoltClock Avatar answered Oct 13 '22 01:10

BoltClock