我有一个带有(id)参数的init方法:
-(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;
}
答案 0 :(得分:7)
通常这意味着在具有冲突参数类型的不同类上有多个initWithSource:
方法名称。请记住,如果变量的类型为id
,则编译器不知道它是什么类。因此,如果在initWithSource:
类型的对象上调用id
并且多个类具有initWithSource:
方法,则编译器基本上只选择其中一个。如果它选择“错误”的那个,那么,你得到一个“明显的Objective-C类型”错误。
那为什么会发生这种情况?我不是百分百确定,但请记住+[TBCTouchDelegate alloc]
会返回id
。因此,链接alloc / init调用等同于:
id o = [TBCTouchDelegate alloc];
touchDelegate = [o initWithSource:self];
因此,您在initWithSource:
类型的变量上调用id
。如果存在冲突的initWithSource:
方法,则可能会出现此编译器错误。
是否存在冲突方法?我检查了系统,唯一有冲突的是NSAppleScript
:
- (id)initWithSource:(NSString *)source;
现在NSAppleScript
是基金会的一部分,但我注意到这是iPhone代码。因此,在编译模拟器而不是设备时,您可能只会遇到此错误?
在任何情况下,如果这是你的问题,你可以通过将alloc / init分成两行来解决它:
touchDelegate = [TBCTouchDelegate alloc];
touchDelegate = [touchDelegate initWithSource:self];
现在,您在完全类型的变量(而不是initWithSource:
- 类型)上调用id
,因此编译器不再需要猜测要选择哪一个。或者您可以从+alloc
投射回报:
touchDelegate = [(TBCTouchDelegate *)[TBCTouchDelegate alloc] initWithSource:self];
另一个解决方案是重命名initWithSource:
以避免冲突,并可能使其更具描述性。你没有说出这个类目前的名称以及“源”是什么,所以我不能抛弃任何可能性。