2012-02-02 10 views
28

Objective-Cブロックプロパティを定義することはできますが、Xcode 4ではフルコード補完が可能ですか?Xcodeコード補完を使用したObjective-Cブロックプロパティ

私はブロックを定義するためのtypedefを使用する場合:

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

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

@property (nonatomic, copy) CompletionBlock completionBlock;

、その後@synthesize私は完全なコードを得ることはありませんプロパティセッターを呼び出すときに完了します。 Xcodeはtypedefを使用します。そのため、コード補完では、ブロックパラメータで完全なブロック構文が使用されず、typedefが使用されます。

Iの代わりのtypedefの完全なブロック構文使用ヘッダにおけるメソッドプロトタイプ定義する場合:

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

した後、私は@synthesize使用を提供セッターは完全なコード補完を使用することに接近私は@synthesizeとしようとすると、最後に

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

:構文だが決定的にそれがパラメータ名を抜けてその後、セッターの実装をオーバーライドしたり、ヘッダにプロトタイプを置く:

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

警告は、プロパティの型がアクセサー・タイプと一致していないことを伝える上げています。どのように構文を完成させようとも、コード補完の完全な構文を持つブロックプロパティとセッターを定義することはできません。私はケーキを食べて食べることができますか?

ありがとうございます!

+0

それは質問をharkens ...魔法のように、動作しますか?機能の低下と半冗長なコード行については?たぶんこれはアップルの言葉です... ___ "しないでください!" ___ ?? –

答えて

32

クラスインターフェイスにコードを1行追加したい場合は、ケーキを食べて食べても間違いありません。

まず、あなたがあなたの質問に行ったようにtypedefをしてブロックを定義し、プロパティを作成:MobileOverloadは彼の答えで指摘したように

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

... 

@property (nonatomic, copy) CompletionBlock completionBlock; 

次に、私たちは、「Xcodeのは、typedefの正しいコード補完を提供することを知っていますスタンドアロンのメソッド宣言で使用されている場合はdブロックになります。それでは、completionBlockのセッターのための明示的な宣言を追加してみましょう。

呼ば
- (void)setCompletionBlock:(CompletionBlock)completionBlock; 

、このメソッドはプロパティの宣言セッターメソッドを解決します。しかし、クラスインタフェースで明示的に定義しているので、Xcodeはそれを見て完全なコード補完を適用します。

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

+2

これは、ありがとう!私はこれについてバグレポートを提出しますので、将来的に明示的なメソッド宣言は必要ないでしょう。 – Andrew

+0

インターフェイスファイルに明示的なセッタ宣言を追加すると、実装が不完全であることを示すプロジェクト警告が表示されます。このセッターをインターフェイスに宣言すると、.mで実装する必要がありますか? – djibouti33

+0

プロパティを宣言していない場合、またはプロパティ定義者が明示的に宣言したものとは異なる定義を持つ場合にのみ、警告が表示されます。 – Matt

4

あなたのクラス内のメソッドへの引数としてブロックを渡すときに、見栄えの良いコード補完を得ることができます。ヘッダファイルでは、私はその後、私はまた、このクラスのヘッダーで宣言した私のメソッドに引数としてそれを使用することができました。この

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

のようなブロックをtypedefさ。 Mファイルで

-(void)doThisWithBlock:(MyCompletionBlock)block; 

は、私は方法

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

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

CodeCompletion2

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

+2

残念ながら、動作は異なります.Xcodeでは、typedefブロックタイプで '@ property'を定義し、手動で定義されたsetterメソッドまたは' @ synthesize'd setterを生成するときに完全ブロック構文を使用しません。 – Andrew

+2

同じ問題が発生しました。 Xcode 4.3.2(4E2002)以降、これは正しいです。あなたはtypedefと明示的なメソッド宣言をあなたのインターフェースセクションで使わなければなりません。完全なコード補完を取得したい場合は、プロパティを使用したり、typedefされたブロックを使用せずにメソッドを定義したりすることはできません。 – Klaas

+0

それはXcodeでこれと同じです(4の後の数字、あなたが夢中なら、私を修正してください)。 UGH! –

0

コードスニペットを使用するとコードスニペットを使用してコード補完を行うことができ、コードスニペットでプレースホルダを使用できます< #PLACE HOLDER#>。 希望すると、これはあなたに役立ちます

1

[OK]をので、私は定義

など、 が実際に入力する/短いを読み取ること物事 が容易になります...警告/エラーになるdoes'tこれを行う場しのぎの方法を考え出しましたその後、私たちの「略語」とマクロなどをプロパティ宣言で完全なフォーマットを使用して...

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

その後..あなたは、その後など、引数の「種類」、のような..

ことを参照することができます0
+ (void)addInputBlock:(TINP)termDidReadString; 

とvoilá...あなたのコードはTINIERになるでしょう!しかし、コード補完はなぜ `typedef`まったく...

enter image description here

関連する問題