web-dev-qa-db-ja.com

Xcodeコード補完を備えたObjective-Cブロックプロパティ

Objective-Cブロックプロパティを定義することは可能ですが、Xcode 4で完全なコード補完がまだありますか?

Typedefを使用してブロックを定義する場合:

typedef void (^CompletionBlock)(MyObject *myObj);

次に、プロパティを定義します。

@property (nonatomic, copy) CompletionBlock completionBlock;

次に、_@synthesize_プロパティを設定します。セッターを呼び出すときに完全なコード補完を取得できません。 Xcodeはtypedefを使用します。そのため、コード補完では、ブロックパラメーターを含む完全なブロック構文を使用せず、typedefを使用します。

Typedefの代わりに完全なブロック構文を使用するメソッドプロトタイプをヘッダーで定義すると、次のようになります。

@property (nonatomic, copy) void (^completionBlock)(MyObject *myObj);

そして、私は_@synthesize_を使用します。提供されたセッターは完全なコード補完構文を使用することに近づきますが、重要なことに、パラメーター名は省略されます。

[self setCompletionBlock:(void (^)(MyObject *)) { ... }

最後に、_@synthesize_を試み、セッターの実装をオーバーライドするか、ヘッダーにプロトタイプを配置した場合:

- (void)setCompletionBlock:(void (^)(MyObject *myObj))completionBlock {...}

プロパティタイプがアクセサータイプと一致しないことを示す警告が表示されます。構文をいかに試そうとしても、コード補完のための完全な構文を持つブロックプロパティとセッターの両方を定義することはできません。ケーキを持って食べてもいいですか?

ありがとう!

33
Andrew

クラスインターフェイスにコードを1行追加する場合は、間違いなくケーキを手に入れて食べることもできます。

まず、typedefを使用してブロックを定義し、質問で行ったようにプロパティを作成します。

typedef void (^CompletionBlock)(MyObject *myObj);

...

@property (nonatomic, copy) CompletionBlock completionBlock;

次に、MobileOverloadが彼の回答で指摘したように、スタンドアロンメソッド宣言で使用した場合、Xcodeがtypedefされたブロックに対して正しいコード補完を提供することがわかります。それでは、completionBlockのセッターの明示的な宣言を追加しましょう:

- (void)setCompletionBlock:(CompletionBlock)completionBlock;

このメソッドが呼び出されると、プロパティによって宣言されたセッターメソッドに解決されます。ただし、クラスインターフェイスで明示的に定義したため、Xcodeはそれを認識し、完全なコード補完を適用します。

したがって、これらの3行すべてを含めると、望ましい結果が得られるはずです。 @propertyステートメントで定義されたセッターが、独自に定義された同じメソッドとは異なるコード補完を持つ必要がある理由がないため、この動作は明らかにXcodeの欠点です。

36
Matt

クラスのメソッドにブロックを引数として渡すと、見栄えのよいコード補完が得られます。ヘッダーファイルで、次のようにブロックをtypedefしました

typedef void (^MyCompletionBlock)(id obj1, id obj2);

次に、このメソッドを、このクラスヘッダーで宣言したメソッドの引数として使用できました。

-(void)doThisWithBlock:(MyCompletionBlock)block;

Mファイルでメソッドを宣言しました

-(void)doThisWithBlock:(MyCompletionBlock)block {
    NSLog(@"Something");
}

そして、私がそれを呼び出すために行ったとき、私はこのような豪華なコード補完を得ました。 CodeCompletion1

CodeCompletion2

うまくいけば、これはあなたの質問に答えます。

4
MobileOverlord

わかりましたので、警告/エラーを発生させない、これを行うための一時的な方法を見つけました... andは実際に物事を作成しますeasier読みやすく/タイプするのが短いなど。

「省略形」でマクロを定義し、次にプロパティ宣言で完全な形式を使用します...

#define TINP NSString*(^)(NSString *typed, const char *raw)
@interface ....
@property (copy) NSString*(^termDidReadString)(NSString *typed, const char *raw);

その後、その「種類」の引数などを参照できます。

+ (void)addInputBlock:(TINP)termDidReadString;

そして、ボイラー...あなたのコードがよりシンプルになるだけではありません!!しかし、コード補完は魅力のように機能します...

enter image description here

1
Alex Gray

完全なコード補完については知りませんが、コードスニペットを使用して動作などのコード補完を取得でき、コードスニペット<#PLACE HOLDER#>でプレースホルダーを使用できます。これがあなたを助けることを願っています

0
Apps 4 U