Objective-C初始化者是否允许共享相同的名称?

Nat*_*att 5 objective-c initializer selector

我在Objective-C中遇到一个奇怪的问题,当我有两个类使用相同名称的初始化器,但是类型不同的参数.例如,假设我创建了类A和B:

啊:

#import <Cocoa/Cocoa.h>

@interface A : NSObject {
}

- (id)initWithNum:(float)theNum;

@end
Run Code Online (Sandbox Code Playgroud)

上午:

#import "A.h"

@implementation A

- (id)initWithNum:(float)theNum
{
    self = [super init];
    if (self != nil) {
        NSLog(@"A: %f", theNum);
    }
    return self;
}

@end
Run Code Online (Sandbox Code Playgroud)

BH:

#import <Cocoa/Cocoa.h>

@interface B : NSObject { 
}

- (id)initWithNum:(int)theNum;

@end
Run Code Online (Sandbox Code Playgroud)

BM:

#import "B.h"

@implementation B

- (id)initWithNum:(int)theNum
{
    self = [super init];
    if (self != nil) {
        NSLog(@"B: %d", theNum);
    }
    return self;
}

@end
Run Code Online (Sandbox Code Playgroud)

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 = [[A alloc] initWithNum:20.0f];   
    B *b = [[B alloc] initWithNum:10];

    [a release];
    [b release];

    [pool drain];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到以下输出:

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
Run Code Online (Sandbox Code Playgroud)

如果我颠倒了导入的顺序,那么它首先导入Bh,我得到:

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
Run Code Online (Sandbox Code Playgroud)

出于某种原因,似乎它正在使用在两个类中首先包含的@interface中定义的数据类型.我做了一些单步执行调试器,发现a和b对象的isa指针最终都是一样的.我还发现,如果我不再使内联的alloc和init调用,两个初始化似乎都能正常工作,例如:

A *a = [A alloc];
[a initWithNum:20.0f];
Run Code Online (Sandbox Code Playgroud)

如果我在创建a和b时使用此约定,我会得到正确的输出,并且每个对象的isa指针似乎都不同.

难道我做错了什么?我原本以为多个类可以有相同的初始化名称,但可能情况并非如此.

Jas*_*oco 5

问题是该+alloc方法返回一个类型的对象,id因此编译器无法决定使用哪个方法签名.您可以通过多种方式强制应用程序选择正确的选择器.一种是从alloc转换回报,所以:

A* a = [(A*)[A alloc] initWithNum:20.f];
B* b = [(B*)[B alloc] initWithNum:10];
Run Code Online (Sandbox Code Playgroud)

或者你可以覆盖你的类上的alloc并返回更具体的东西,虽然我不会自己这样做.所以:

+ (A*)alloc { return [super alloc]; }
Run Code Online (Sandbox Code Playgroud)

最后,以及我个人选择的内容,使选择器更具描述性:

// A.h
- (id)initWithFloat:(float)theNum;

// B.h
- (id)initWithInteger:(int)theNum;
Run Code Online (Sandbox Code Playgroud)