cha*_*bag 19 delegates objective-c super uigesturerecognizer respondstoselector
好的,我有点困惑.
我有一个UIScrollView的子类,这是我尝试像UI元素一样水平滚动"表视图".UIScrollView本身设置它在内部使用的UIGestureRecognizers,它似乎将自己设置为那些UIGestureRecognizers的委托.我在我的水平表元素/单元格上也有自己的UIGestureRecognizer设置,我自己的类设置为我自己的UIGestureRecognizer的委托.由于我的类是UIScrollView的子类,在运行时,UIGcureRecognizer委托调用来到我的类,用于UIScrollView内置的UIGestureRecognizers和我自己的UIGestureRecognizers.有点像PITA,但我们可以通过传递我们不关心的东西来解决这个问题.
-(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;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是检查[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委托例程使用此代码(显然是不同的选择器).
感谢您的任何见解.
jjb*_*rka 24
除非你覆盖对类中选择器的响应,否则在调用super时将使用默认实现,这将检查当前实例.如果要查看某种对象的实例是否响应选择器使用+(BOOL)instancesRespondToSelector:(SEL)aSelector;
这将检查对象及其父对象.所以在你的情况下你想要以下内容:
[UIScrollView instancesRespondToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)]
Run Code Online (Sandbox Code Playgroud)
Jos*_*ell 17
[super respondsToSelector:@selector(frobnosticate:)] 不做你的想法.
它转到超类,获取那里的实现respondsToSelector:,然后在当前对象上运行它.换句话说,super表示相同的对象self,它只是在继承树中启动方法查找一步.
所以你respondsToSelector:在这个子类上运行,它回复"是",但后来试图gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:从超类中获取,而超类没有它.
要检查直接超类的实例,你会instancesRespondToSelector:像jjburka推荐的那样使用,但我建议[self superclass]作为主题,如下:
[[self superclass] instancesRespondToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)];
Run Code Online (Sandbox Code Playgroud)
这避免了硬编码类名.
在查看其他答案后,最好的解决方案是使用[[MapControllerSublcass1 superclass] instancesRespondToSelector:_cmd].如果您使用上面推荐的内容,例如[BaseClass instancesRespondToSelector:_cmd],您遇到了更改类层次结构的问题,并且意外忘记更改BaseClass为新的超类或子类.
[[self superclass] instancesRespondToSelector:...]如上面评论中所解释的那样是不正确的,它实际上是在Apple的文档中说明的(参见respondsToSelector:在NSObjct中).只有当你拥有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];
}
}
Run Code Online (Sandbox Code Playgroud)
MapControllerSubclass2.m:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
if ([[MapControllerSubclass2 superclass] instancesRespondToSelector:_cmd]) {
[super mapView:mapView regionWillChangeAnimated:animated];
}
}
Run Code Online (Sandbox Code Playgroud)