如何忽略“X没有可见的@interface声明select器”?

在ARC之前,我有一个“X可能不响应xxx”的警告 ,这是一个非常无害的警告,并不妨碍它编译。 现在,我试图将我的项目转换为ARC,并且我有一个“没有可见的@接口X表示select器xxx” 错误 ,这阻止了编译。

我确切地知道我在做什么,为什么警告在那里,我可以告诉你,程序是正确的。 以前,编译器编译没有问题,现在不应该停止编译。

确实,类X的接口没有声明这个select器,但是X是一个dynamic处理任何发送给它的消息的类,使用forwardInvocation:这是关于Objective-C的美丽事物之一),所以它的接口不可能声明所有可以被调用的select器。 select器声明在某个地方,而不是X.

我确切地知道我在做什么,为什么警告在那里,我可以告诉你,程序是正确的。

好的 – 只需使用objc_msgSend等。 直接如果你想做编译器的工作。

确实,类X的接口没有声明这个select器,但是X是一个dynamic处理任何发送给它的消息的类,使用forwardInvocation :(这是关于Objective-C的美丽事物之一),所以它的接口不可能声明所有可以被调用的select器。 select器被声明在某个地方,而不是X.

如果声明太繁琐而不够繁琐,那么这些消息似乎与您的程序使用select器相矛盾…听起来就像生成代码的危险区域,并且有很大的人为干预。

也许你应该考虑声明一个协议,这样编译器至less可以为你正确地设置消息调用 – 如果你改变或者破坏了一些东西,它有机会适应或者通知你。

我不确定,但我相信在ARC之下,编译器可以看到方法签名更重要,因为它需要知道需要什么内存pipe理。 所以你要么需要:

  1. 通过一个普通的方法声明你正在使用的方法(理想情况下,在真实的接收器上,但是如果没有别的类别,即使只在NSObject )。
  2. 通过NSInvocation或其他一些类似的方式手动执行操作,对内存pipe理负责(这可能会非常棘手,因为您必须与ARC进行桥接)。

更新 :我刚刚检查了clang源代码,事实确实如此 – 使用ARC时需要签名。 这不仅仅是在说谎。 🙂

确实,类X的接口没有声明这个select器,但是X是一个dynamic处理任何发送给它的消息的类,使用forwardInvocation :(这是关于Objective-C的美丽事物之一),所以它的接口不可能声明所有可以被调用的select器。 select器被声明在某个地方,而不是X.

如果要放弃静态types信息,则将其转换为标识。 或者,如果你的对象是另一个类的代理,也许会转换到这个类。

只要方法是在头文件中声明的(无论如何都需要这样做),并且参数types没有歧义,这应该修复错误。

如果你感兴趣的是为什么这只是一个启用ARC的问题,请检查这个问题的答案,我问: 为什么'没有已知的select器x的方法'ARC下的硬错误?