5

我有一个带有 (id) 参数的 init 方法:


    -(id) initWithObject:(id) obj;

我试图这样称呼它:


    [[MyClass alloc] initWithObject:self];

但是 XCode 抱怨该参数是“不同的 Objective-C 类型”(这通常表示类型不匹配或间接错误级别)。

如果我明确地将 self 转换为 (id),警告就会消失。在任何一种情况下,代码都会按预期运行。有趣的是,在下一行中,我将 self 传递给另一个也采用 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;
}
4

1 回答 1

7

通常这意味着initWithSource:在不同的类上有多个方法名称,它们的参数类型相互冲突。请记住,如果一个变量被键入,因为id编译器不知道它是什么类。因此,如果您调用initWithSource:一个id-typed 对象并且多个类都有一个initWithSource:方法,那么编译器基本上只会选择两者之一。如果它选择了“错误的”,那么你会得到一个“distinct Objective-C type”错误。

那么为什么这会发生在你身上呢?我不是 100% 确定,但请记住+[TBCTouchDelegate alloc]返回一个id. 因此链接 alloc/init 调用等价于:

id o = [TBCTouchDelegate alloc];
touchDelegate = [o initWithSource:self];

因此,您正在调用initWithSource:一个id-typed 变量。如果存在冲突的initWithSource:方法,您可能会收到此编译器错误。

有冲突的方法吗?我检查了系统,唯一有冲突的是NSAppleScript

- (id)initWithSource:(NSString *)source;

现在NSAppleScript Foundation 的一部分,但我注意到这是 iPhone 代码。所以也许你只在为模拟器而不是设备编译时得到这个错误?

无论如何,如果这是您的问题,您可以通过将 alloc/init 拆分为两条不同的行来解决它:

touchDelegate = [TBCTouchDelegate alloc];
touchDelegate = [touchDelegate initWithSource:self];

现在,您调用initWithSource:的是全类型变量(而不是id-typed),因此编译器不再需要猜测要选择哪个变量。或者您可以从以下位置投射回报+alloc

touchDelegate = [(TBCTouchDelegate *)[TBCTouchDelegate alloc] initWithSource:self];

另一种解决方案是重命名initWithSource:以避免冲突,并可能使其更具描述性。你没有说这个类当前的名字是什么,也没有说“源”是什么,所以我不能排除任何可能性。

于 2008-11-23T19:51:26.593 回答