OK,我有点困惑。
我的UIScrollView的子类,这是我在一个水平滚动的“表视图”像UI元素的尝试。 UIScrollView的本身设置UIGestureRecognizers内部使用,它似乎将自己设置为代表的那些UIGestureRecognizers。 我也有我的水平表格元素/电池我自己UIGestureRecognizer设置和我自己的类集合为委托我自己UIGestureRecognizer。 由于我的类的UIScrollView的子类,在运行时,UIGestureRecognizer委托调用来我班的两个UIScrollView的内置UIGestureRecognizers和我自己的UIGestureRecognizers。 皮塔饼的一点,但我们可以通过传递上,我们不关心的那些解决这个问题。
-(BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]])
return NO;
else
{
if ([super respondsToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)])
return [super gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer];
else
return NO;
}
}
问题是,检查[super respondsToSelector:@selector()]
返回YES,但是当我后来居然把它return [super gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer];
我得到下面的异常
2012-08-31 12:02:06.156 MyApp的[35875:707] - [MyAppHorizontalImageScroller gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]:无法识别的选择发送到实例0x21dd50
我本来以为它应该显示
- [UIScrollView中gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]
但是,这可能是确定。 但问题是,它说,它响应,然后没有。
另外两个UIGestureRecognizer委托程序与此代码的工作(不同的选择很明显)。
感谢您的任何见解。
除非你重写响应在你的类选择器您将使用默认的实现,当你调用super将检查当前实例。 如果你想看看一个对象类型的实例响应选择使用+(BOOL)instancesRespondToSelector:(SEL)aSelector;
这将检查的对象和它的父对象。 所以你的情况,你想以下几点:
[UIScrollView instancesRespondToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)]
[super respondsToSelector:@selector(frobnosticate:)]
不会做你的想法。
它去超,得到实施respondsToSelector:
在那里,然后运行它的当前对象 。 换句话说, super
代表同一对象self
,它只是开始的方法查找在继承树高一个台阶。
所以,你正在运行respondsToSelector:
在这个子类,其中回答“是”,但后来试图让gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
从超,不拥有它。
要检查的直接超类的实例,你可以使用instancesRespondToSelector:
作为jjburka建议,但我会建议[self superclass]
作为受试者,就像这样:
[[self superclass] instancesRespondToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)];
这避免了硬编码的类名称。
看着其他的答案后,最好的解决办法是使用[[MapControllerSublcass1 superclass] instancesRespondToSelector:_cmd]
如果您使用的是上面推荐的,像[BaseClass instancesRespondToSelector:_cmd]
你碰上改变你的类层次结构,不慎忘记改变的问题BaseClass
新的超类或子类。
[[self superclass] instancesRespondToSelector:...]
如上的评论解释,它实际上是这么说的上是不正确苹果的文档(:在NSObjct见respondsToSelector) 。 只有当你拥有1级子类的作品,所以它给你的错觉 ,这是一个实际的解决方案。 我爱上了它。
和[[super class] instancesRespondToSelector:...]
不起作用,会这样问题的关键所在。
例如,我有一个BaseMapController
实现一些在方法MKMapViewDelegate
,但它没有实现mapView:regionWillChangeAnimated:
MapControllerSublcass1
从继承BaseMapController
。 而MapControllerSubclass2
从继承MapControllerSublcass1
。
在我的代码,我有这样的事情,并能正常工作。
MapControllerSublcass1.m:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
if ([[MapControllerSublcass1 superclass] instancesRespondToSelector:_cmd]) {
[super mapView:mapView regionWillChangeAnimated:animated];
}
}
MapControllerSubclass2.m:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
if ([[MapControllerSubclass2 superclass] instancesRespondToSelector:_cmd]) {
[super mapView:mapView regionWillChangeAnimated:animated];
}
}
你打电话的时候
[super respondsToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)]
这是要超和运行其实现respondsToSelector
。 这看起来的情况下(在这种情况下,您的自定义滚动视图),并确定它是否响应该选择与否。
你打电话的时候
[super gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer];
您尝试使用超类实现该方法,在这种情况下不存在发送消息,导致崩溃。
貌似jjburka得首先 - 你需要调用
[UIScrollView instancesRespondToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)]
另外,如果你使用它不会崩溃-[super performSelector:]
从无法识别的选择-执行选择得到落实情况的选择的。 它会崩溃的无限递归。
至于有人用同一案件的总结,也有原来的问题两个问题:
- 检查是否超响应该选择,这是建议的@jjburka最好使用完成
instancesRespondToSelector:
- 其实调用的是超类的方法,无需编译器抱怨,即使它在一个私人的标头的声明。 这可以通过在一个类别重新声明它整齐地实现(见这个问题 )。
将其组合在一起这给:
// … In subclass implementation file
@interface UIScrollView () <UIGestureRecognizerDelegate> @end
// … In gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
if ([UIScrollView instancesRespondToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)]) {
return [super gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer];
}
文章来源: super respondsToSelector: returns true but actually calling super (selector) gives “unrecognized selector sent to instance”