5

(id) 引数を取る init メソッドがあります。


    -(id) initWithObject:(id) obj;

私はそれを次のように呼ぼうとしています:


    [[MyClass alloc] initWithObject:self];

しかし、XCode は、引数が「明確な Objective-C 型」であることについて不平を言っています (通常、型の不一致または間接エラーのレベルを示します)。

self を (id) に明示的にキャストすると、警告は消えます。どちらの場合でも、コードは期待どおりに実行されます。興味深いことに、次の行で、id を受け取る別のメソッドに self を渡していますが、これは正常に機能します。

何か微妙なものが欠けているのではないかと思っています-それともコンパイラの特異性ですか?

それが必要な理由がはっきりするまで、キャストするだけでは完全に快適ではありません。

[編集]

追加のコードを提供するよう求められました。他に関連するものがたくさんあるかどうかはわかりません。これが呼び出しを行う実際のコードです。それ自体が 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オブジェクトを呼び出し、複数のクラスにinitWithSource:メソッドがある場合、コンパイラは基本的に 2 つのうちの 1 つを選択します。「間違った」ものを選択すると、「明確なObjective-Cタイプ」エラーが発生します。

では、なぜこれがあなたに起こっているのですか?100% 確信はありませんが、 . が+[TBCTouchDelegate alloc]返されることを覚えておいてidください。したがって、 alloc/init 呼び出しを連鎖させることは、これと同等です。

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

したがって、型付き変数を呼び出しinitWithSource:ています。id競合するinitWithSource:メソッドがある場合、このコンパイラ エラーが発生する可能性があります。

競合する方法はありますか?システムをチェックしたところ、唯一競合していたのはNSAppleScript:

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

現在NSAppleScript Foundation の一部ですが、これは iPhone のコードであることに気付きました。おそらく、デバイスではなく、シミュレーター用にコンパイルするときにのみこのエラーが発生するのでしょうか?

いずれにせよ、これが問題である場合は、alloc/init を 2 つの異なる行に分割することで回避できます。

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

initWithSource:これで、 (-typed ではなく) 完全に型指定された変数を呼び出しているidため、コンパイラはどれを選択するかを推測する必要がなくなりました。または、リターンをキャストすることもできます+alloc:

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

別の解決策は、名前を変更initWithSource:して競合を回避し、おそらくよりわかりやすいものにすることです。クラスの現在の名前や「ソース」の目的については何も言わないので、可能性を捨てることはできません。

于 2008-11-23T19:51:26.593 に答える