我正在开发一个项目,我有一个具有UIView
属性的类。我还定义了一个类,它是UIView
的子类,它定义了某个方法。如果我有以下代码,我在构建时会收到警告:
// In this example, myView is UIView property which *may* contain a UIView or
// my subclassed-UIView which has the myMethod method
if([myView respondsToSelector:@selector(myMethod)]){
[myView myMethod]
}
警告是“UIView可能无法响应'-myMethod'”。警告显然不能阻止应用程序的构建,但我只想弄清楚如何处理它。这是正确的方法吗?有没有办法停止这个警告?
答案 0 :(得分:5)
警告仅仅是因为编译器不知道该视图是否是您的自定义子类。当然,在运行时它会正常工作,因为它将是一个子类。您有两种方法可以解决它:
[myView performSelector:@selector(myMethod)];
(因此编译器根本不检查方法调用)
或者,更好:
[(MyViewClass *)myView myMethod];
这样编译器的行为就好像对象确实是你的视图子类(当然你执行检查之后)。
就此而言,检查你的课程而不是方法是有意义的:
if ([myView isKindOfClass:[MyViewClass class]]) { ...
答案 1 :(得分:1)
您可以使用:
[myView performSelector:@selector(myMethod)];
答案 2 :(得分:1)
这是一个静态类型警告,告诉您声明变量的类型不响应该选择器。因为你实际上正在使用你已经确认对选择器做出响应的子类,你知道这不是问题,但是编译器不够聪明,无法解决这个问题。有几种方法可以解决这个问题。按安全顺序递减:
将变量转换为实际上 对选择器(特定类或协议)做出响应的内容。您仍然需要导入适当的标头,否则编译器会怀疑您输入错误的内容。哪个选项最好取决于您的情况(例如,是否有一个“正确”类要转换为)。
[(id<SomeProtocolWiththatSelector>)myView myMethod];
[(SomeUIViewSubclass *)myView myMethod];
将变量强制转换为id
以禁用静态类型检查。您仍然需要使用声明导入标头,以便编译器知道某些方法存在,或者仍然会给出“我不确定这是否是真正的方法”警告。
[(id)myView myMethod];
使用performSelector:
。这不会在编译时进行任何检查,因此除了Foundation之外你不需要导入任何标题,但编译器也不会捕获任何拼写错误,因此你所犯的任何错误都意味着程序在运行时会出现繁荣。
[myView performSelector:@selector(myMethod)];