33

A simple example of my problem:

"Within the BlahDataController.h"

@interface BlahDataController : NSObject
-(NSString *)aMethod:(NSString *)theString;
@end

"Within the BlahDataController.m"

#import "BlahDataController.h"
@implementation BlahDataController

-(NSString *)aMethod:(NSString *)theString
{
    return @"Something";
}

@end

"Within BobViewController.h"

@interface BobViewController : NSObject
-(void)aMethodOfSomeSort;
@end

"Within BobViewController.m"

#import "BobViewController.h"
#import "BlahDataController.h"

@implementation BobViewController

-(void)aMethodOfSomeSort
{
    BlahDataController *blahDataController = [[BlahDataController alloc] init];
    NSLog(@"%@",[blahDataController aMethod:@"Variable"]);
}

@end

On the line "NSLog(@"%@",[blahDataController aMethod:@"Variable"]);" I'm receiving the error: "No visible @interface for 'BlahDataController' declares the selector 'aMethod:'"

Anyone know why this error is occurring?

-=-=-=-=-=-=-=-=-=-=-

The thing is, in my actual program, I have this same implementation and it works fine for hundreds of methods created this way. However, every so often, I'll receive this error on a newly created method. I didn't make it any differently. It just won't recognize it's newly created existence.

-=-=-=-=-=-=-=-=-=-=-

This is how I'm currently going around it, although I have no idea why the compiler accepts this way, but not the other:

Modify BobViewController.m:

#import "BobViewController.h"
#import "BlahDataController.h"
#import "AnotherDataController.h"

@implementation BobViewController

-(void)aMethodOfSomeSort
{
    BlahDataController *blahDataController = [[BlahDataController alloc] init];
    AnotherDataController *anotherDataController = [[AnotherDataController alloc] init];
    [anotherDataController fixedMethod:blahDataController theString:@"Variable"];
}

@end

"Within the AnotherDataController.h"

@interface AnotherDataController : NSObject
-(void)fixedMethod:(BlahDataController *)blahDataController theString:(NSString *)theString;
@end

"Within the AnotherDataController.m"

#import "AnotherDataController.h"
#import "BlahDataController.h"
@implementation AnotherDataController

-(void)fixedMethod:(BlahDataController *)blahDataController theString:(NSString *)theString
{
    NSLog(@"%@",[blahDataController aMethod:theString]);
}
@end

And....it works just fine...So I imagine xcode is just failing to recognize the method in one class, and working as it should in another...Man, I have no idea why this error is occurring...

-=-=-

Minor Update:
Doing the entire "xcode dance" didn't solve the issue
1) Clean Build
2) Delete Derived Data
3) Completely Close XCode and reopen

Highrule
  • 1,915
  • 3
  • 19
  • 23
  • Is it a persistent problem? Does it go away after a clean and rebuild? – Dan F May 23 '12 at 21:03
  • I've tried a full clean and rebuild, but to no avail! – Highrule May 23 '12 at 21:10
  • Thats really interesting, one class recognizes the method, the other doesn't...Are you sure its not something really silly, like a typo in the method name either where you declared it or where you're calling it, that you just aren't making the second time? – Dan F May 23 '12 at 21:12
  • This is probably just xcode so have you tried the full xcode dance? cmd + alt + shift + K to clean the build folder. Then delete derived data. Then close xcode completely and reopen... – Paul.s May 23 '12 at 21:15
  • Well that's the first thing I read it could be...however, I'm not typing the method, I'm using the nice autofill feature (type the letter a and the entire "aMethod:" appears...however, one controller the method autofills, the other doesn't autofill and assumes it doesn't exist – Highrule May 23 '12 at 21:15
  • Delete derived data?...Haven't done that one...can you elaborate a tad? – Highrule May 23 '12 at 21:16
  • Open up the Organizer -> click the projects tab -> select your project on the left -> Click delete derived data. It has a description underneath for what it is if you are concerned... (also quick side not make sure you @ reply to people or they won't know you have responded) – Paul.s May 23 '12 at 21:26
  • @Paul.s Cool, thanks. I was wondering where all those derived files were...I actually went to the folder they were at and deleted them all as well...However, even after completing the entire xcode dance...the problem is still there! – Highrule May 23 '12 at 21:31
  • Is it weirdness with NSLog? What happens if call the method on its own line of code and store the result in a variable, which you then send to NSLog? – Philip May 24 '12 at 02:18
  • @Philip Oh, I just had NSLog there as an example. In actuality, it's a different line of code there. The problem involves the method just not being recognized...The assumption is a compiler/xcode issue rather than a programming issue, but I have yet to solve the problem...I have circumvented the problem as listed above, however – Highrule May 24 '12 at 14:43
  • Solution works for me: `rm -rf Pods/ Podfile.lock` and `pod install` again. – DawnSong Sep 06 '19 at 11:24

5 Answers5

59

tl;dr - There's a duplicate file somewhere in the project! Go hunt it down and destroy it mercilessly!

Ok, for all those in the future with this issue; this is what the problem was.

I had made BlahDataController months ago. About a week ago, I restructured the folders of the project and moved BlahDataController from a folder called "Blah" to another folder called "Data".

When I changed the code for BlahDataController within the "Data" folder, one of my classes could see the changed code, however, another class couldn't.

What ended up being the issue was that when I moved BlahDataController, it actually created a copy of it. So I had a BlahDataController in the "Data" folder, and an older BlahDataController in the "Blah" folder. Even though the older BlahDataController was no longer attached to the project in the project manager (left side of xcode), the fact that the physical file still existed in the folder caused this issue.

After deleting the duplicate older copy of BlahDataController, the issue was resolved.

Community
  • 1
  • 1
Highrule
  • 1,915
  • 3
  • 19
  • 23
  • wow. I was ready to punch my computer...why the heck wouldn't duplicate files at least generate a compiler warning? – Aaron Brown Jul 02 '12 at 23:51
  • Wow be careful.. I had this exact same problem.. I had dragged a few classes from another old project in Finder, and added them to my current project and worked on them there(With "Copy if necessary" or whatever ON), then I noticed this bug. I found the old project in Finder, and completely deleted those files. When re-entering the project, the names of the copied classes were red. So the project had me work on the original files even though I can confirm that copies of them were made in my current project. I have to do a lot of work from scratch.. :/ Damn bug.. – Sti Aug 24 '12 at 20:14
  • 2
    The way it got there was a little bit different, but the root cause was the same: duplicate file. What gets me is that when I told XCode to "jump to definition" of the class, I was still getting the class I knew about - i.e., the one with the "missing" selector. Gah! Thanks! – Sasha Nov 14 '12 at 02:07
  • In my case was not a duplicate. Was copying some files from another project and linked from that one instead of copying – Carlos Ricardo Mar 09 '13 at 13:47
  • Dang, I spent over an hour trying to figure out why Xcode was being lame....thanks for this answer, it fixed my issue. – 5StringRyan Oct 13 '13 at 17:01
  • Solution works for me: `rm -rf Pods/ Podfile.lock` and `pod install` again. If you are right, there is something wrong with `pod install` – DawnSong Sep 06 '19 at 11:24
4

If someone stumbles upon a similar problem, in my case I did some refactoring using "Find & Replace" feature (ignoring case) and I obtained something like this:

SomeClass* SomeClass = [[SomeClass alloc] init];
[SomeClass instanceMethod];

and it was saying: "No visible @interface for 'SomeClass' declares the method 'alloc'. So in my case the problem was I renamed the instance variable to upper case. The solution was:

SomeClass* someClass = [[SomeClass alloc] init];
[someClass instanceMethod];

PS: I recommend using the "Refactor" feature in Xcode instead of "Find & Replace" if possible.

Maxim Chetrusca
  • 3,262
  • 1
  • 32
  • 28
3

Note: not the answer for this exact question, but I got here searching for the same compiler error.

Make sure you know if you are calling the instance method or static method:

@interface SomeClass

+(void) SomeMethod;

vs.

-(void) SomeMethod;

These are different.

[SomeClass SomeMethod];

vs.

[[[SomeClass alloc] init] SomeMethod];
Nick
  • 2,735
  • 1
  • 29
  • 36
2

Also note that this might happen (e.g. with the master/detail project template) if the

"Other Linker Flags"

value is set to

-ObjC

as required by some frameworks, e.g. RestKit (issue at RestKits github page: https://github.com/RestKit/RestKit/issues/1153)

Lennert
  • 925
  • 1
  • 7
  • 21
1

Yes I had the same problem. I had this working perfect in my Paid Target though when I changed to my Free Target I got this error.

No visible @interface for 'GameOverScene' declares the selector mesageToDisplayOnLabel:

  • to fix this the spelling of my method call was different to the method I was calling.

    -(void)messageToDisplayOnLabel //I'm missing the s in "message" in my method call Doh!
    {
    //method code
    }

  • check the spelling of the method you are calling might help.

uplearned.com
  • 3,393
  • 5
  • 44
  • 59