Statically-typed Objective-C Object seems to think it's a NSCFArray instead
I'm trying to pick up Objective-C but ran into a roadblock experimenting with the object syntax. When I try to call a method from a class I've defined, though, I'm getting this as output.
11:29:19 $ /Users/rsmith/Projects/Objective-C/Expedition/a.out; exit
Loading command-line wrapper...load successful!
2010-08-26 11:29:19.070 a.out[1619] *** _NSAutoreleaseNoPool(): Object 0x303ff0 of class NSCFString autoreleased with no pool in place - just leaking
2010-08-26 11:29:19.071 a.out[1619] *** -[NSCFArray getChild]: selector not recognized [self = 0x302d70]
2010-08-26 11:29:19.071 a.out[1619] *** _NSAutoreleaseNoPool(): Object 0x304bd0 of class NSCFString autoreleased with no pool in place - just leaking
2010-08-26 11:29:19.071 a.out[1619] *** _NSAutoreleaseNoPool(): Object 0x3050f0 of class NSCFString autoreleased with no pool in place - just leaking
2010-08-26 11:29:19.071 a.out[1619] *** _NSAutoreleaseNoPool(): Object 0x3050d0 of class NSException autoreleased with no pool in place - just leaking
2010-08-26 11:29:19.071 a.out[1619] *** Uncaught exception: <NSInvalidArgumentException> *** -[NSCFArray getChild]: selector not recognized [self = 0x302d70]
Trace/BPT trap
logout
[Process completed]
Memory leaks aside, it seems to be not recognizing my method because it thinks the object is a NSCFArray. What am I doing wrong here? The full wrapper code and class definitions are as follows:
wrapper.m
#import "AbstractController.h"
int main() {
fprintf(stdout, "Loading command-line wrapper...");
fprintf(stdout, "load successful!\n");
AbstractController * controller = [[AbstractController alloc] init];
[controller getChild];
return 0;
} // end function main
AbstractController.h
#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
@interface AbstractController : NSObject
{
AbstractController * parent;
NSMutableArray * children;
}
// instance methods
- (id)init;
- (AbstractController *)getAncestor;
- (AbstractController *)getChild;
- (AbstractController *)getHeir;
- (AbstractController *)getParent;
@end // interface AbstractController
AbstractController.m
#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import "AbstractController.h"
@implementation AbstractController : NSObject
- (id)init {
children = [[NSMutableArray alloc] init];
} // end method init
- (AbstractController *)getParent {
return parent;
} // end method getParent
- (AbstractController *)getChild {
AbstractController * child = ([children count] > 0) ? [children objectAtIndex:0] : self;
开发者_如何学Python return child;
} // end method getChild
- (AbstractController *)getAncestor {
AbstractController * ancestor;
ancestor = (parent) ? [parent getAncestor] : self;
return ancestor;
} // end method getAncestor
- (AbstractController *)getHeir {
AbstractController * child = [self getChild];
AbstractController * heir;
heir = (child) ? [child getHeir] : self;
return heir;
} // end method getHeir
@end // implementation AbstractController
First, put an autorelease pool in your main() to shut up all the autorelease problems.
Next, pay attention to compiler warnings. If there is a warning, there is a bug or potential bug in your code. And there should definitely be a warning that documents exactly what is wrong.
Namely, your -init
method is wrong:
- (id)init {
children = [[NSMutableArray alloc] init];
} // end method init
You don't end it with return self;
. Or, more specifically, you don't:
- init {
self = [super init];
if (self) {
children = [[NSMutableArray alloc] init];
}
return self;
}
Also, you should try and follow the same patterns as Apple's frameworks and APIs. Namely, don't prefix those methods with get
. Finally, make sure you add a dealloc
method, too.
The only thing that looks weird here off the top of my head is the " : NSObject
" at the @implementation tag. I've never seen the inheritance declared in @implementation, just @interface. No idea why that would cause the error you're seeing, though.
精彩评论