我见过以下方式定义的Objective-c协议:
@protocol MyProtocol <SomeOtherProtocol>
// ...
@end
为什么协议采用其他协议?我特别好奇为什么协议会采用NSObject
协议。
答案 0 :(得分:22)
它与类的继承概念相同。 如果协议采用另一种协议,它“继承”该采用的协议的声明方法。
NSObject
协议特别声明respondsToSelector:
等方法。因此,如果您声明@protocol
具有@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
如果respondsToSelector
被声明为实施myDelegate
的类型,您将只能在myDelegate上调用respondsToSelector
(否则您会收到一些警告) 。这就是<SomeProtocol>
协议需要采用<NSObject>
协议的原因,协议本身就是声明这种方法。
您可能会将id<SomeProtocol>
视为“任何对象,无论其类型(id
),它只需要实现SomeProtocol
中声明的方法,包括父级中声明的方法协议NSObject
。所以它可以是任何类型的对象,但因为SomeProtocol
采用NSObject
协议本身,所以可以保证你可以调用respondsToSelector
在此对象上,允许您在调用之前检查对象是否实现给定方法(如果它是可选的)。
请注意,您可能也不会SomeProtocol
采用NSObject
协议,而是将您的变量声明为id<SomeProtocol,NSObject> myDelegate
,以便仍然可以调用respondsToSelector:
。但是如果你这样做,你将需要在使用这个协议的任何地方以这种方式声明你所有的变量...所以这使得SomeProtocol
直接采用NSObject
协议更合乎逻辑;)
答案 1 :(得分:2)
继承...................