2011-01-17 22 views
1

私は、目的のCブロックに関するいくつかの厄介な問題に遭遇しました。私たちはこのようなコード持っている、のは、言ってみましょう:このコードで目的Cブロックの宣言が矛盾しています

//Class1.h 
#import <Foundation/Foundation.h> 

typedef void (^Class1Callback)(BOOL bl); 

@interface Class1 : NSObject { } 

- (id)initWithCallback:(Class1Callback)callback; 

@end 

//Class2.h 
#import <Foundation/Foundation.h> 

typedef enum Class2Enum { Foo, Bar, FooBar } Class2Enum; 

typedef void (^Class2Callback)(Class2Enum ce); 

@interface Class2 : NSObject { } 

- (id)initWithCallback:(Class2Callback)callback; 

@end 

//main.c 
#import "Class1.h" 
#import "Class2.h" 

int main(int argc, char *argv[]) { 
    Class1 *class1 = [[Class1 alloc] initWithCallback:^(BOOL bl){ }]; 
    Class2 *class2 = [[Class2 alloc] initWithCallback:^(Class2Enum ce){ }]; 
} 

が、私はエラーを取得しています「の初期化、互換性のないブロックポインタ型 『を無効(^)(列挙Class2Enum)』、期待 『Class1Callback』」行で

Class2 *class2 = [[Class2 alloc] initWithCallback:^(Class2Enum ce){ }]; 

しかし、私はちょうどmain.cの中に逆輸入する場合、すなわち

#import "Class2.h" 
#import "Class1.h" 

エラーがその場所と説明を変更する - 今ではラインに

です
Class1 *class1 = [[Class1 alloc] initWithCallback:^(BOOL bl){ }]; 

と説明があり、「期待 『ボイド(^)(BOOL)』を初期化し、互換性のないブロックポインタ型、 『Class2Callback』」

はなぜコンパイラは期待しない「Class2Callback」メソッドの宣言は、ブロックタイプと言うとき、 Class1Callbackですか? 私はそれがなぜ起こっているのか、どこで私が求めるべきか、答えを見つけるために何を読むべきか、何も知らない。助言がありますか?

答えて

7

+allocは、Objective-Cの汎用オブジェクト型であるidを返します。そのため、コンパイラは-initWithCallback:の意味を知りません。なぜなら、idは理論上どちらかのクラスのインスタンスになる可能性があるからです。 、

また
Class1 *class1 = [(Class1 *)[Class1 alloc] initWithCallback: ...]; 

彼らは同じではありませんので、あなたの初期化メソッドの名前を変更し、コンパイラができるようになります:あなたは、このような紛争の例でインスタンス化しているクラスへ+alloc呼び出しの結果をキャストする必要がありますそれらを区別する。できれば、もっと説明何かを試してみてください:私は、関連する質問に答えました

- (id)initWithCompletionHandler: (Class1Callback)handler; 
- (id)initWithProgressHandler: (Class2Callback)handler; 
+0

OPが同様に参照することもできます。http://stackoverflow.com/questions/4705567/how-do-warnings-on -undefined-selectors-work-in-objective-c/4706071#4706071 –

+0

ありがとう、私はallocリターンのidについて完全に忘れました。命名については、実際のコードでは同じ名前を持つinitメソッドが必要ですが、それは単なる例です。 –

+0

@Alexander一般に、ランタイムは指定されたセレクタのメソッド記述を1つしか保持しないため、同じ名前(同じ名前/同じセレクタ、異なる戻り値/引数型)を持つ異なるメソッドを持つことはお勧めできません。最初のコメントでリンクした質問を参照してください。 –

関連する問題