2010-11-19 10 views
2

私のプロジェクトでは3つのクラスがありますが、Apple、Orange、Pearと呼んでいます。XCodeの間違った警告は「Xプロトコルを実装していません」

AppleとOrangeの両方にデリゲートプロパティがあります。
彼らは両方とも、AppleDelegateとOrangeDelegateというヘッダファイルにプロトコルを定義しています。彼らはそれぞれ同様のシグネチャを持つ初期化子があり

- (id)initWithDelegate:(id<AppleDelegate>)delegate 
- (id)initWithDelegate:(id<OrangeDelegate>)delegate 

梨はOrangeDelegateを実装し、次のように定義されています。結果

Orange *anOrange = [[[Orange alloc] initWithDelegate:self] autorelease]; 

@interface Pear : NSObject <OrangeDelegate> 

インサイド梨、私はこの電話をかけますこのコンパイラの警告:

Class 'Pear' does not implement the 'AppleDelegate' protocol 

コンパイラはイニシャライザのプロトコルを認識しないようです。言い換えれば、それだけで、両方のために、この署名を認識します。

- (id)initWithDelegate:(id)delegate 

私は梨で初期化子の「定義へジャンプ」をクリックしたとき、それはオプションとして両方のクラスが表示されますので。

私のメソッドの名前を変更する以外にこの警告を修正する方法はありますか?

+0

奇妙なことに、梨をリンゴの代議員に割り当てることはできませんでした。私は思っています。 – Daniel

+0

@ダニエル - それは私が思ったものですが、私はそうではありません。私はAppleを追加し、警告が表示されました。 OrangeとPearの両方がその前に存在し、警告なしでコンパイルされました。 Appleを追加したときにOrangeやPearのいずれも修正されなかったが、突然警告を発し始めた。 – DougW

答えて

3

問題は、 'alloc'はNSObjectから継承され、 'id'型を返すように定義されたメソッドです。したがって、次のようになります。

[Orange alloc] 

「id」タイプのオブジェクトを評価します。そのオブジェクトでinitWithDelegateを呼び出すと、コンパイラはその型を知らず、この場合、間違った型を推測します。ですから、と警告を排除することができます:コンストラクタはObjective-Cの中言語レベルの機能、単なる慣習ではないので

Orange *anOrange = [[(Orange *)[Orange alloc] initWithDelegate:self] autorelease]; 

だから、基本的に、それはです。

編集:下記を参照してください。何よりも複雑ないだろうオレンジ

+ (Orange *)alloc; 

、::私は別のソリューションを追加するだろうと思い、私はそれは、部分的に設計上の決定だと思い

+ (Orange *)alloc 
{ 
    return [super alloc]; 
} 

を - クラスがいることを知るための責任を負わなければなりませんそれらのコンストラクタメソッドは他のクラスの名前と衝突することがあります。同じコンストラクタを使用して複数のクラス定義をインポートするファイルは、あいまいさの原因となります。構文の単純な見た目はクリンチャーかもしれませんが。

+0

ああ、そうですね。私は自分自身を(id)にキャストすることも警告を排除することが分かった。どちらか一方はちょっと恥ずかしくて醜いですが、そのように見えるか、またはイニシャライザの名前を変更します。ありがとう。 – DougW

+0

もう少し考えてみました(私はこの問題について適切な助言を見たことがない、私は最初の原則から答えている)、私はNSObjectから継承するのではなく、initをオーバーライドできると思います。私は答えを編集しました。なぜなら、ソースコードで簡単に言えるからです。 – Tommy

関連する問題