为什么Objective-c协议采用其他协议?
我见过Objective-c协议以以下方式定义:为什么Objective-c协议采用其他协议?,objective-c,ios,protocols,nsobject,Objective C,Ios,Protocols,Nsobject,我见过Objective-c协议以以下方式定义: @protocol MyProtocol <SomeOtherProtocol> // ... @end @protocol-MyProtocol // ... @结束 为什么协议会采用其他协议?我特别好奇为什么协议会采用NSObject协议。继承………..它与类继承的概念完全相同。 如果一个协议采用另一个协议,它将“继承”该采用协议的声明方法 NSObject协议特别声明了respondsToSelector:等方法。因此,如果
@protocol MyProtocol <SomeOtherProtocol>
// ...
@end
@protocol-MyProtocol
// ...
@结束
为什么协议会采用其他协议?我特别好奇为什么协议会采用
NSObject
协议。继承………..它与类继承的概念完全相同。
如果一个协议采用另一个协议,它将“继承”该采用协议的声明方法
NSObject
协议特别声明了respondsToSelector:
等方法。因此,如果您声明了一个具有@可选方法的@协议
,这尤其有用,因为当您随后调用符合此协议的对象上的方法时,如果此方法是可选的,则需要在调用前检查对象是否响应该方法
如果myDelegate
被声明为实现respondsToSelector
的类型,则只能在myDelegate上调用respondsToSelector
(否则会出现一些警告)。这就是
协议需要采用
协议的原因,该协议本身声明了此方法
您可能认为id
是“任何对象,无论其类型(id
),它只需实现SomeProtocol
中声明的方法,包括父协议NSObject
中声明的方法。因此,它可以是除之外的任何类型的对象。因为SomeProtocol
采用了NSObject
协议本身,因此可以保证允许您调用respondsToS此对象上的elector
,允许您在调用该对象之前检查该对象是否实现了给定的方法(如果该方法是可选的)
请注意,您也可以不使用SomeProtocol
采用NSObject
协议,而是将变量声明为id myDelegate
,这样您仍然可以调用respondsToSelector:
。但是如果这样做,您将需要在使用此协议的任何地方以这种方式声明所有变量……因此这就是much使SomeProtocol
直接采用NSObject
协议更合理;)请注意,为了避免警告,严格来说没有必要使原始协议符合NSObject
。与其使用id myDelegate
,不如使用NSObject*myDelegate
。是的,这也可以是一个解决方案。But然后插入对类型的依赖(即使这种情况不太可能发生,有些人可能会使用NSProxy或其他什么;我同意这是罕见的,但无论如何)因此,这有点违反了OOP的对象化原则。如果没有理由强迫用户使用显式继承NSObject的类,而只需要它实现一些给定的方法,那么为什么要强迫它呢?正确的方法是使用NSObject
协议和id
类型,而不是NSObject类型,to保持类型之间的弱链接,避免强类型。更准确地说,是接口继承。
@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