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 :(.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With