代码之家  ›  专栏  ›  技术社区  ›  philsquared

为什么我需要将自我转换为id?

  •  5
  • philsquared  · 技术社区  · 16 年前

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

    
        -(id) initWithObject:(id) obj;
    

    
        [[MyClass alloc] initWithObject:self];
    

    “间接类型”或“间接类型”指的是“不匹配的目标类型”(XCode通常指的是不同级别的错误)。

    如果我明确地将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;
    }
    

    
    -(id) initWithSource:(id) sourceObject
    {
        self = [super init];
        if (self != nil) 
        {
            // Uninteresting initialisation snipped
        }
        return self;
    }
    
    1 回复  |  直到 9 年前
        1
  •  7
  •   Dave Dribin    16 年前

    通常这意味着有多个 initWithSource: 具有冲突参数类型的不同类上的方法名称。记住,如果变量类型为 id 编译器不知道它是什么类。因此,如果你打电话 initWithSource: 身份证件 方法,编译器本质上只选择其中一个。如果它选择了一个“错误”的,那么,你会得到一个“不同的Objective-C类型”的错误。

    那为什么这会发生在你身上?我不是百分之百确定,但记住这一点 +[TBCTouchDelegate alloc] 返回一个 身份证件 . 因此,链接alloc/init调用相当于:

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

    因此,你在打电话 initWithSource: 身份证件 -类型化变量。如果有冲突 initWithSource: 方法,则可能会出现此编译器错误。

    NSAppleScript :

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

    基金会的一部分,但我注意到这是iPhone代码。因此,您可能只在为模拟器而不是设备编译时才会出现此错误?

    在任何情况下,如果这是您的问题,您可以通过将alloc/init拆分为两行来解决:

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

    现在,你在打电话吗 在全类型变量上(而不是 身份证件 +alloc :

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

    initWithSource: