我已经使用可选方法实现了一个协议,在调用方法中,我希望在发送消息之前将respondsToSelector:
发送到self.delegate
,但这不会编译。失败消息是:
选择器'respondsToSelector'的已知实例方法。
作为解决方案,我“清理”了如下所示的代表,它编译了......
//MyClass.h:
@class MyClass;
@Protocol MyClassDelegate
- (void)myClass:(MyClass *)sender willDoSomething:(BOOL)animated;
@end
@interface MyClass : UIViewController
@property (nonatomic, weak) id<MyClassDelegate> delegate;
@end
和
//MyClass.m:
...
@synthesize delegate = _delegate;
...
id sanitizedDelegate = self.delegate; //Hmmmm... why does this work?
if ([sanitizedDelegate respondsToSelector:@selector(myClass:willDoSomething:)]) {
[self.delegate myClass:self willDoSomething:animated];
}
我检查了一些帖子,包括this one,但它没有回答编译失败问题。
此外,替代访问器不起作用......
[self delegate]
//or
_delegate
有没有人看过这个或者可以建议更好的处理方式?
IOS 5.0:(9A334),Xcode 4.2.1(4D502)
答案 0 :(得分:98)
-respondsToSelector:
是NSObject上的一个方法。假设您的id
委托实际上是一个NSObject,并将其转换为:
[(NSObject*)self.delegate respondsToSelector:@selector(myClass:willDoSomething:)]
或者,更好的是,使您的委托明确地成为NSObject:
@property (nonatomic, weak) NSObject<MyClassDelegate>* delegate;
或者使协议成为NSObject的子协议:
@protocol MyClassDelegate <NSObject>
答案 1 :(得分:15)
基本上你说你的委托只受你的<MyClassDelegate>
协议的约束,所以编译器假定那些是唯一可用的方法。您需要做的是让协议扩展<NSObject>
,如下所示:
@Protocol MyClassDelegate <NSObject>
- (void)myClass:(MyClass *)sender willDoSomething:(BOOL)animated;
@end
这样编译器就知道任何符合您协议的对象也符合定义<NSObject>
的{{1}}协议。