我见过这样定义的Objective-C的协议:为什么Objective-c协议采用其他协议?
@protocol MyProtocol <SomeOtherProtocol>
// ...
@end
为什么协议采取其他协议?我特别好奇为什么协议会采用NSObject
协议。
我见过这样定义的Objective-C的协议:为什么Objective-c协议采用其他协议?
@protocol MyProtocol <SomeOtherProtocol>
// ...
@end
为什么协议采取其他协议?我特别好奇为什么协议会采用NSObject
协议。
它与类的继承简单相同。 如果一个协议采用另一种协议,它会“继承”这个采用协议的声明方法。
NSObject
协议特别声明方法,如respondsToSelector:
。因此,如果您声明具有@optional
方法的@protocol
特别有用,因为当您随后将调用符合此协议的对象的方法时,如果此方法是可选的,则在调用它之前需要检查对象是否响应该方法。
@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
协议;)
请注意,为避免警告,使原始协议符合'NSObject'不是必须的。而不是使用'id myDelegate',使用'NSObject * myDelegate'。 –
2011-09-22 20:42:02
是的,这也可以是一个解决方案。但是它插入了对类型的依赖(即使这种情况不太可能发生,有些可能会使用NSProxy或其他类型;我同意这种情况很少见但很少见),所以它违反了OOP的抽象原则。如果没有理由强迫用户使用显式继承NSObject的类,而只需要实现某些给定的方法,为什么强制它...那么正确的方法是使用NSObject协议和类型而不是NSObject类型来保持类型之间的薄弱链接并避免强类型。 – AliSoftware