如果对象响应仍然会发出警告

时间:2010-08-04 16:50:19

标签: objective-c xcode

我正在开发一个项目,我有一个具有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'”。警告显然不能阻止应用程序的构建,但我只想弄清楚如何处理它。这是正确的方法吗?有没有办法停止这个警告?

3 个答案:

答案 0 :(得分:5)

警告仅仅是因为编译器不知道该视图是否是您的自定义子类。当然,在运行时它会正常工作,因为它将是一个子类。您有两种方法可以解决它:

[myView performSelector:@selector(myMethod)];

(因此编译器根本不检查方法调用)

或者,更好:

[(MyViewClass *)myView  myMethod];

这样编译器的行为就好像对象确实是你的视图子类(当然你执行检查之后)。

就此而言,检查你的课程而不是方法是有意义的:

if ([myView isKindOfClass:[MyViewClass class]]) { ...

答案 1 :(得分:1)

您可以使用:

[myView performSelector:@selector(myMethod)];

答案 2 :(得分:1)

这是一个静态类型警告,告诉您声明变量的类型不响应该选择器。因为你实际上正在使用你已经确认对选择器做出响应的子类,你知道这不是问题,但是编译器不够聪明,无法解决这个问题。有几种方法可以解决这个问题。按安全顺序递减:

  1. 将变量转换为实际上 对选择器(特定类或协议)做出响应的内容。您仍然需要导入适当的标头,否则编译器会怀疑您输入错误的内容。哪个选项最好取决于您的情况(例如,是否有一个“正确”类要转换为)。

    [(id<SomeProtocolWiththatSelector>)myView myMethod];
    [(SomeUIViewSubclass *)myView myMethod];
    
  2. 将变量强制转换为id以禁用静态类型检查。您仍然需要使用声明导入标头,以便编译器知道某些方法存在,或者仍然会给出“我不确定这是否是真正的方法”警告。

    [(id)myView myMethod];
    
  3. 使用performSelector:。这不会在编译时进行任何检查,因此除了Foundation之外你不需要导入任何标题,但编译器也不会捕获任何拼写错误,因此你所犯的任何错误都意味着程序在运行时会出现繁荣。

    [myView performSelector:@selector(myMethod)];