selector - Are Objective-C initializers allowed to share the same name? -
i'm running odd issue in objective-c when have 2 classes using initializers of same name, differently-typed arguments. example, let's create classes , b:
a.h:
#import <cocoa/cocoa.h> @interface : nsobject { } - (id)initwithnum:(float)thenum; @end
a.m:
#import "a.h" @implementation - (id)initwithnum:(float)thenum { self = [super init]; if (self != nil) { nslog(@"a: %f", thenum); } return self; } @end
b.h:
#import <cocoa/cocoa.h> @interface b : nsobject { } - (id)initwithnum:(int)thenum; @end
b.m:
#import "b.h" @implementation b - (id)initwithnum:(int)thenum { self = [super init]; if (self != nil) { nslog(@"b: %d", thenum); } return self; } @end
main.m:
#import <foundation/foundation.h> #import "a.h" #import "b.h" int main (int argc, const char * argv[]) { nsautoreleasepool * pool = [[nsautoreleasepool alloc] init]; *a = [[a alloc] initwithnum:20.0f]; b *b = [[b alloc] initwithnum:10]; [a release]; [b release]; [pool drain]; return 0; }
when run this, following output:
2010-04-26 20:44:06.820 fntest[14617:a0f] a: 20.000000 2010-04-26 20:44:06.823 fntest[14617:a0f] b: 1
if reverse order of imports imports b.h first, get:
2010-04-26 20:45:03.034 fntest[14635:a0f] a: 0.000000 2010-04-26 20:45:03.038 fntest[14635:a0f] b: 10
for reason, seems it's using data type defined in whichever @interface gets included first both classes. did stepping through debugger , found isa pointer both , b objects ends same. found out if no longer make alloc , init calls inline, both initializations seem work properly, e.g.:
a *a = [a alloc]; [a initwithnum:20.0f];
if use convention when create both , b, right output , isa pointers seem different each object.
am doing wrong? have thought multiple classes have same initializer names, perhaps not case.
the problem +alloc
method returns object of type id
compiler can't decide method signature use. can force application choose correct selector in number of ways. 1 cast return alloc, so:
a* = [(a*)[a alloc] initwithnum:20.f]; b* b = [(b*)[b alloc] initwithnum:10];
or override alloc on class , return more specific, although wouldn't myself. so:
+ (a*)alloc { return [super alloc]; }
finally, , chose, make selectors more descriptive:
// a.h - (id)initwithfloat:(float)thenum; // b.h - (id)initwithinteger:(int)thenum;
Comments
Post a Comment