self.delegate respondsToSelector:...不编译

时间:2012-03-06 07:04:49

标签: xcode ios5

我已经使用可选方法实现了一个协议,在调用方法中,我希望在发送消息之前将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)

2 个答案:

答案 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}}协议。