I've seen Objective-c protocols defined in the following way:
@protocol MyProtocol <SomeOtherProtocol>
// ...
@end
Why do protocols adopt other protocols? I'm especially curious why a protocol would adopt the NSObject
protocol.
In Objective-C, protocols are declared with the “@protocol” keyword. Below is an example of declaring a protocol containing one required method. In Swift, the syntax is a little different but the idea is the same. In Objective-C, you add the protocol name in angle brackets beside the class interface declaration.
Objective-C allows you to define protocols, which declare the methods expected to be used for a particular situation. This chapter describes the syntax to define a formal protocol, and explains how to mark a class interface as conforming to a protocol, which means that the class must implement the required methods.
Objective-C Language Protocols Conforming to Protocols It is also possible for a class to conform to multiple protocols, by separating them with comma. Like when conforming to a single protocol, the class must implement each required method of each protocols, and each optional method you choose to implement.
An Objective-C delegate is an object that has been assigned to the delegate property another object. To create one, you define a class that implements the delegate methods you're interested in, and mark that class as implementing the delegate protocol. For example, suppose you have a UIWebView .
It is simply the same concept as inheritance for classes. If a protocol adopt another protocol, it "inherits" the declared methods of this adopted protocol.
The NSObject
protocol especially declares methods such as respondsToSelector:
. So this is especially useful if you declare a @protocol
that have @optional
methods, because when you will then call methods on objects conforming this protocol, you will need to check if the object responds to the method before calling it if this method is optional.
@protocol SomeProtocol <NSObject>
-(void)requiredMethod;
@optional
-(void)optionalMethod;
@end
@interface SomeObject : NSObject
-(void)testMyDelegate;
@property(nonatomic, assign) id<SomeProtocol> myDelegate;
@end
@implementation SomeObject
@synthesize myDelegate
-(void)testMyDelegate {
// Here you can call requiredMethod without any checking because it is a required (non-optional) method
[self.myDelegate requiredMethod];
// But as "optionalMethod" is @optional, you have to check if myDelegate implements this method before calling it!
if ([myDelegate respondsToSelector:@selector(optionalMethod)]) {
// And only call it if it is implemented by the receiver
[myDelegate optionalMethod];
}
}
@end
You will only be able to call respondsToSelector
on myDelegate if myDelegate
is declared as a type that implements respondsToSelector
(otherwise you will have some warnings). That's why the <SomeProtocol>
protocol needs to adopt itself the <NSObject>
protocol, which itself declares this method.
You may think of id<SomeProtocol>
as "any object, whatever its type (id
), it just has to implement the methods declared in SomeProtocol
, including the methods declared in the parent protocol NSObject
. So it can be an object of any type but because SomeProtocol
adopts the NSObject
protocol itself, it is guaranteed that you are allowed to call respondsToSelector
on this object, allowing you to check if the object implements a given method before calling it if it is optional.
Note that you may also not make SomeProtocol
adopt the NSObject
protocol and instead declare your variable as id<SomeProtocol,NSObject> myDelegate
so that you can still call respondsToSelector:
. But if you do that you will need to declare all your variables this way everywhere you use this protocol... So this is much more logical to make SomeProtocol
directly adopt the NSObject
protocol ;)
Inheritance...................
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