Why do Objective-c protocols adopt other protocols?
I've seen Objective-c protocols defined in the following way:
@protoco开发者_如何学JAVAl MyProtocol <SomeOtherProtocol>
// ...
@end
Why do protocols adopt other protocols? I'm especially curious why a protocol would adopt the NSObject
protocol.
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...................
精彩评论