为什么我需要将自己投入ID?
我有一个init方法,它接受一个(ID)的说法:为什么我需要将自己投入ID?
-(id) initWithObject:(id) obj;
我想这样称呼它:
[[MyClass alloc] initWithObject:self];
但Xcode是抱怨的说法是一个“明显Objective-C类型“(通常表示类型不匹配或间接错误级别)。
如果我明确地将自己投给(id),警告消失。无论哪种情况,代码都按预期运行。 有趣的是,在接下来的一行中,我将自己传递给另一个也需要一个id的方法,并且工作正常。
我想知道如果我错过了一些微妙的东西 - 或者它是编译器的特点吗?
我不是很舒服,只是把它铸造出来,直到我确信它有必要的原因。
[编辑]
我被要求提供更多的代码。不确定还有其他什么是相关的。这是我打电话的实际代码。请注意,它本身在init方法中。这是调用initWithSource
多数民众赞成给予警告:
-(id) initWithFrame:(CGRect) frame
{
self = [super initWithFrame: frame];
if(self)
{
delegate = nil;
touchDelegate = [[TBCTouchDelegate alloc] initWithSource:self];
[touchDelegate.viewWasTappedEvent addTarget: self action:@selector(viewWasTapped:)];
}
return self;
}
而这里被称为init方法:
-(id) initWithSource:(id) sourceObject
{
self = [super init];
if (self != nil)
{
// Uninteresting initialisation snipped
}
return self;
}
通常,这意味着有不同的班,相互冲突的参数类型多initWithSource:
方法名。请记住,如果一个变量输入为id
,编译器不知道它是什么类。因此,如果你在一个id
型对象上调用initWithSource:
,并且多个类有一个initWithSource:
方法,编译器本质上只是挑选其中的一个。如果它选择了“错误的”,那么你会得到一个“明显的Objective-C类型”错误。
那么为什么会发生在你身上呢?我不是100%确定,但请记住+[TBCTouchDelegate alloc]
返回id
。因此链/初始化调用页头是相同的:
id o = [TBCTouchDelegate alloc];
touchDelegate = [o initWithSource:self];
因此,您是在id
-typed变量调用initWithSource:
。如果有冲突的方法,您可能会遇到此编译器错误。
有没有矛盾的方法?我检查了系统,唯一的冲突的一个是NSAppleScript
:
- (id)initWithSource:(NSString *)source;
现在NSAppleScript
是基金会一部分,但我注意到,这是iPhone的代码。所以编译模拟器时可能只会出现这个错误,而不是设备?
在任何情况下,如果这是你的问题,你能避开它通过拆分分配/初始化到两个不同的路线:
touchDelegate = [TBCTouchDelegate alloc];
touchDelegate = [touchDelegate initWithSource:self];
现在,你在一个完全类型的变量调用initWithSource:
(而不是id
-type),所以编译器不再需要猜测选择哪一个。或者你可以从+alloc
转换返回:
touchDelegate = [(TBCTouchDelegate *)[TBCTouchDelegate alloc] initWithSource:self];
另一种解决方案是重命名initWithSource:
以避免冲突,或许使其更具有描述性。你不会说目前班级名字是什么,也不是说“源”是什么,所以我不能抛弃任何可能性。
您可能想在此发布更多的代码;没有什么会跳出来的,但只有两条线可以使用,这很难说。 – 2008-11-23 17:26:36
同意Ben,但需要考虑的一件事是声明了initWithObject方法吗? – 2008-11-23 17:53:52