1

私はObjectiveCブロックに関していくつかの本当に厄介な問題に遭遇しました。たとえば、次のようなコードがあります。

//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){ }];
}

このコードでは、「互換性のないブロックポインタ型が'void(^)(enum Class2Enum)'を初期化しています。'Class1Callback'が必要です」というエラーが表示されます。

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

しかし、main.cでインポートを逆にすると、つまり

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

エラーはその場所と説明を変更します-今それは一列に並んでいます

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

説明は「'void(^)(BOOL)'を初期化する互換性のないブロックポインタ型、期待される'Class2Callback'」です。

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

4

1 に答える 1

7

+allocidObjective-Cの汎用オブジェクトタイプであるを返します。そのため、理論的にはどちらかのクラスのインスタンスである可能性があるため、コンパイラはあなたがどちら-initWithCallback:を意味するのかわかりません。id次のような競合が発生した場合は、インスタンス化するクラスに呼び出しの結果をキャストする必要があり+allocます。

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

または、初期化メソッドの名前を変更して同一にならないようにします。そうすれば、コンパイラーはそれらを区別できるようになります。可能であれば、より説明的なものを試してください。

- (id)initWithCompletionHandler: (Class1Callback)handler;
- (id)initWithProgressHandler: (Class2Callback)handler;
于 2011-01-17T16:25:42.517 に答える