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指针似乎都不同.
难道我做错了什么?我原本以为多个类可以有相同的初始化名称,但可能情况并非如此.
问题是该+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)
归档时间: |
|
查看次数: |
183 次 |
最近记录: |