Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ignore "No visible @interface for X declares the selector"?

Before ARC, I had an "X may not respond to xxx" warning, which is a pretty harmless warning which does not prevent it from compiling. Now, I am trying to convert my project to ARC, and I have an "No visible @interface for X declares the selector xxx" error, which prevents it from compiling.

I know exactly what I am doing, and why the warning was there, and I can tell you that the program is correct. Previously, the compiler compiled it with no problem, and should not now stop it from compiling.

It is true that class X's interface does not declare that selector, but X is a class that dynamically handles any message with any selector sent to it, using forwardInvocation: (that is one of the beautiful things about Objective-C), so its interface cannot possibly declare all the selectors that can be called on it. And the selector is declared somewhere, just not on X.

like image 752
user102008 Avatar asked Nov 21 '12 02:11

user102008


3 Answers

I know exactly what I am doing, and why the warning was there, and I can tell you that the program is correct.

OK -- Just use objc_msgSend et al. directly if you want to do the compiler's work.

It is true that class X's interface does not declare that selector, but X is a class that dynamically handles any message with any selector sent to it, using forwardInvocation: (that is one of the beautiful things about Objective-C), so its interface cannot possibly declare all the selectors that can be called on it. And the selector is declared somewhere, just not on X.

If it's too tedious to declare but not tedious enough to use in messaging that seems to contradict your program's use of the selector… Sounds like the dangerous territory of generated code with significant human intervention.

Perhaps you should consider declaring a protocol so the compiler can at least set the message calls up correctly for you -- and if you change or break something, it has a chance to adapt or notify you.

like image 57
justin Avatar answered Oct 04 '22 18:10

justin


I'm not certain, but I believe under ARC it's more important that the compiler can see a method signature, because it needs to know what memory management is needed. So you'll either need to:

  1. Declare the methods you're using via one of the normal methods (i.e. ideally on the real receiver, but if nothing else as a category, even if only on NSObject).
  2. Do things manually via NSInvocation or some other similar means, taking full responsibility for memory management (which can be tricky, as you'll have to bridge to and from ARC).

Update: I just checked the clang source, and this is indeed the case - it needs the signature when using ARC. It's not just trying to be mean. :)

like image 27
Wade Tregaskis Avatar answered Oct 04 '22 19:10

Wade Tregaskis


It is true that class X's interface does not declare that selector, but X is a class that dynamically handles any message with any selector sent to it, using forwardInvocation: (that is one of the beautiful things about Objective-C), so its interface cannot possibly declare all the selectors that can be called on it. And the selector is declared somewhere, just not on X.

Cast to id if you want to discard the static type information. Or if your object is a proxy for another class, maybe cast to that class.

So long as the method is declared somewhere in a header (which needed to be the case anyway), and there is no ambiguity with argument types, this should fix the error.

If you're interested in why this only is an issue with ARC enabled, check the answer to this question I asked: Why is 'no known method for selector x' a hard error under ARC?

like image 27
Chris Devereux Avatar answered Oct 04 '22 19:10

Chris Devereux