views:

342

answers:

3

Here's an odd one. I have a class named TileMap with the following interface:

@interface TileMap : NSObject
{
 int *data;
 int tilesWide;
 int tilesHigh;
 NSString *imageName;
}

+ (id)mapNamed:(NSString *)filename;
- (id)initWithFile:(NSString *)filename;

@end

The implementation looks like this:

@implementation TileMap

+ (id)mapNamed:(NSString *)filename
{
 return [[self alloc] initWithFile:filename];
}

- (id)initWithFile:(NSString *)filename
{
 if (self = [super init])
 {
  // ...
 }
 return self;
}


@end

But when I add a call to [TileMap mapNamed:@"map.plist"]; to my application Xcode warns:

'TileMap' may not respond to '+mapNamed:'

The application compiles fine and calls to NSLog within TileMap-initWithFile: are logged. I noticed that Xcode's syntax coloring was off for this class and method so I tried renaming both the class and the method separately. The only combination that eliminated the warning and syntax coloring issues was to rename both the class and the method.

Am I colliding with some undocumented framework class or method? Find in Documentation doesn't reveal anything. Find in Project only reveals the call, interface definition and the implementation. I'm stumped (not that it takes much). Is there a way around this without munging my existing naming conventions?

+5  A: 

Did you #import the TileMap.h header? Did you save your TileMap.h header?

Dave DeLong
*Hangs head in shame.*I have a framework.h that imports all my framework headers like so: // ... #import "State.h" #import "TileMap.h" // ...I then import framework.h into non-framework files, in this case TitleState.h (which extends `State`).None of the other classes and methods that are imported in this way cause a warning or syntax coloring oddities but you're right. Removing the `#import "TileMap.h"` from framework.h and adding it directly to TitleState.m eliminates the warning (the syntax coloring issues persist but I can live with that).
Shaun Inman
I was thinking that this answered my question but thinking about it some more, why is it not a problem if I rename the class and method?
Shaun Inman
+2  A: 

Turns out my project directory ended up with two TileMap.h and TileMap.m files—visible from the Finder but not in Xcode. One, a complete interface and implementation, in my root project directory. The other just a bare NSObject subclass in my framework subdirectory. Not sure how that happened. Deleting the latter resolved the problem. Thanks for the help just the same Dave.

Shaun Inman
+1  A: 

Shaun,

besides the problem you asked about, you also have a memory leak in +mapNamed:. The following line returns a non-autoreleased object with a retain count of +1, which basically gives ownership to the caller:

return [[self alloc] initWithFile:filename];

According to the Memory Management Programming Guide for Cocoa, you should return autoreleased objects from convenience methods, such as this:

return [[[self alloc] initWithFile:filename] autorelease];

If you have Snow Leopard and Xcode 3.2, you might want to try running the static analyzer to find mistakes such as this one by pressing Cmd+Shift+A.

Alexander Repty
Thanks Alexander, that's good to know.
Shaun Inman