views:

45

answers:

1

Hi all,

I came from a java background, and I was trying to use protocol like a java interface.

In java you can have an object implement an interface and pass it to a method like this:

public interface MyInterface {
 void myMethod();
}

public class MyObject implements MyInterface {
 void myMethod() {// operations}
}



public class MyFactory {
  static void doSomething(MyInterface obj) {
     obj.myMethod();
  }
}

public void main(String[] args) {
 // get instance of MyInterface from a given factory
 MyInterface obj = new MyObject();
 // call method
 MyFactory.doSomething(obj);
}

I was wondering if it's possible to do the same with objective-c, maybe with other syntax.

The way I found is to declare a protocol

@protocol MyProtocol
-(NSUInteger)someMethod;
@end

then my object would "adopt" that protocol and in a specific method I could write:

-(int) add:(NSObject*)object {
 if ([object conformsToProtocol:@protocol(MyProtocol)]) {
   // I get a warning
   [object someMethod];
 } else {
   // other staff
 }
}

The first question would be how to remove the warning, but then in any case other caller could still pass wrong object to the class, since the check is done inside method. Can you point out some other possible way for this ?

thanks Leonardo

+3  A: 

You can make the compiler do the (static) checking for you. Change you method signature to:

-(int) add:(id<MyProtocol>)object

That tells the compiler, that object can be of any class that conforms to MyProtocol. It will now warn you, if you try to call add: with an object of a class that does not conform.

Edit:

To make usage of objects that conform to MyProtocol easier, it's helpful let MyProtocol extend NSObject:

@protocol MyProtocol <NSObject>
...
@end

Now you can send messages like retain, release or respondsToSelector: to objects with a static type of id <MyProtocol>

Especially the last is helpful in cases where you use the @optional keyword in the protocol.

Nikolai Ruhe
great, that seems to work, however I got a compiler warning on line:if ([object conformsToProtocol:@protocol(MyProtocol)]) saying that object does not respond to conformsToProtocol. That seems to disappear if I replace in method signature id<MyProtocol with NSObject<MyProtocol>, I am a bit confused on which to use
Leonardo
You don't have to test by `conformsToProtocol`. If you try to `add:` an object which doesn't conform to `MyProtocol`, the compiler warns you. So, **if you take care of all the warnings**, it's guaranteed that always an object conforming the protocol is passed.
Yuji
@Leonardo: See edit.
Nikolai Ruhe
@Yuji: Thanks for making that clear.
Nikolai Ruhe