0

我正在尝试使用此方法关闭超级视图[self.superview buttonPressedClose];

我已经在我的超级视图中实现了该方法,并且一切正常。

但它在编译期间给了我一个警告“ UIView 可能无法响应 'buttonPressedClose' ”。

如果我将其更改为以下行,它不会给我警报,但这是正确的方法吗?

if ([self.superview respondsToSelector:@selector(buttonPressedClose)]) {
    [self.superview performSelector:@selector(buttonPressedClose) withObject:nil afterDelay:0.0];
}

谢谢。

**编辑错字..

4

2 回答 2

4

这是有问题的错字还是您的代码中的错字?

if ([self.superview respondsToSelector:@selector(buttonPressedClose)]) {
                                                   //  vv here
[self.superview performSelector:@selector(buttonPressedCLose) withObject:nil afterDelay:0.0];
}

通常,self.superview返回一个类型为 的对象UIView,并且您buttonPressedClose是一个未在UIView. 这就是你收到警告的原因。

您可能希望转换self.superview为所需的类型,例如:

[(MyView *)self.superview buttonPressedClose];

或者让它更加神秘并强制转换为id- 编译器不会检查选择器的存在:

[(id)self.superview buttonPressedClose];

也就是说,上述所有解决方案都有点臭。

关于零延迟的一件非常重要的事情-performSelector:不会执行选择器,而是将选择器执行发布到线程的运行循环并在控制返回到运行循环时执行它(即,当调用堆栈为空时)。所以在正常情况下你不会喜欢使用它。

于 2011-10-15T17:42:03.577 回答
0

“这是正确的做法吗?”

不,没有理由这样做。afterDelay:0仅在您不想立即执行时使用。如果你想立即执行它,那么你应该使用performSelector:without afterDelay:.

但是performSelector:像这样直接使用没有任何好处。它等同于直接调用该方法,并且是一种更复杂的方式。您收到的警告纯粹是静态类型检查问题。类型 ( UIView *) 不保证具有该方法。您需要将其转换为支持该方法的预期视图类型,或将其转换id为关闭方法检查。当您使用performSelector:时,这也绕过了方法的静态类型检查,因此严格来说,它并不比将其转换为id然后调用它更好。

于 2012-01-25T03:48:08.700 回答