I have three classes which implement the same protocol, and have the same parent class which doesn't implement the protocol. Normally I would have the protocol as pure virtual functions in the parent class but I couldn't find an Objective-C way to do that.
I want to utilize polymorphism on these subclasses by declaring pure virtual functions in the superclass then have the children implement those functions. However the only Objective-C way I've found to do this is to have each child explicitly decide to implement a protocol, when I do it this way the superclass doesn't know the children will implement that protocol so there are compile time warnings all over the place.
Some pseudo-code if that didn't make sense:
@interface superclass: NSObject
{}
@interface child1: superclass<MyProtocol>
{}
@interface child2: superclass<MyProtocol>
{}
The consumer of these classes:
@class child1
@class child2
@class superclass
@interface SomeViewController: UIViewController
{
child1 *oneView;
child2 *otherView;
superclass *currentView;
}
-(void) someMethod
{
[currentView protocolFunction];
}
The only nice way I've found to do pure virtual functions in Objective-C is a hack by putting [self doesNotRecognizeSelector:_cmd];
in the parent class, but it isn't ideal since it will cause runtime errors rather than compile time.
Optional Protocol methods can be marked as optional using the @optional keyword. Corresponding to the @optional modal keyword, there is a @required keyword to formally denote the semantics of the default behavior. You can use @optional and @required to partition your protocol into sections as you see fit.
You can have properties in a protocol, provided every class that conforms to your protocol have a corresponding @synthesize for that property, or provide a getter and setter. But with a class category you generally can't add instance variables to a class.
Interface and Implementation In Objective C, the file where the declaration of class is done is called the interface file and the file where the class is defined is called the implementation file.
Objective-C developers commonly use dynamic checking rather than compile-time checking in these situations because the language and the frameworks support it so well. So for example, you could write your method like this:
- (void)someMethod
{
// See if the object in currentView conforms to MyProtocol
//
if ([currentView conformsToProtocol:@protocol(MyProtocol)])
{
// Cast currentView to the protocol, since we checked to make
// sure it conforms to it. This keeps the compiler happy.
//
[(SuperClass<MyProtocol> *) currentView protocolMethod];
}
}
I was able to get the compiler to warn me correctly by making the superclass *currentView
property look like this:
@property (nonatomic, retain) superclass<MyProtocol> *currentView;
Alternatively you can use the following
if ([unknownObject conformsToProtocol:@protocol(MyProtocol)])
[unknownObject performSelector:@selector(methodInProtocol)];
instead of the following if you just want to suppress the warning.
if ([unknownObject conformsToProtocol:@protocol(MyProtocol)])
[unknownObject methodInProtocol]; // will cause warning
performSelector: will only work if the number of arguments is zero or one. More flexible invocations can be achieved with NSInvocation.
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