2013-04-19 9 views
8

Cocoaは、非同期操作のためのコールバックメソッドを提供するために、代理人を広範囲に使用します。しかし、私は個人的にはデリゲートモデルを嫌い、どのように非常に特殊な子演算のハンドラを使って現在のクラスを汚染しているのですか。 UIAlertViewは完璧な例です。Objective-Cで匿名の代理オブジェクトを作成する

したがって、ブロックを介してデリゲートプロトコル(例えばUIAlertViewDelegateなど)の要件を満たす匿名デリゲートオブジェクトを作成し、デリゲート参照が必要な場合はどこでもこの匿名オブジェクトを渡すことができますか?

私はそうのようなものを想像:

id myDelegate = @{ 
    alertView:alertView didDismissWithButtonIndex:index =^{ 
     ... 
    } 
}; 

UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:... message:... delegate:myDelegate cancelButtonTitle:... otherButtonTitles:...; 
[alertView show]; 

私が聞いたのObjective-Cは、いくつかの良好な動的言語機能を持っていますが、私は単にオブジェクトにメソッド/セレクターを追加する方法がわかりません。これは比較的簡単な方法で行うことができますか?

+1

1か月前の完全に汎用的な代議員に関する質問があります:http://stackoverflow.com/q/15438410/603977、どこかで 'UIAlertViewDegate'に固有の古い質問がありますが、瞬間 –

+1

もちろん、デリゲート用に全く異なるオブジェクトを作成することはできます。それは、例えばあなたのViewControllerである必要はありません。 (しかし、Objective-Cブロックは私の頭を爆発させるので避けている。) –

+1

Apple側は、Mac側のNSOpenPanelのように、ブロックベースのAPIをUIAlertViewのようなものに追加してくれることを願っている。 –

答えて

5

はい、あなたが言及する言語機能はobjective-c runtimeで公開されていますが、デリゲートクラスを動的に作成する組み込みの機能はなく、ランタイムAPIは最も使いやすいものではありません。

A2DynamicDelegateと呼ばれるライブラリがあります。これは、あなたが話していることを正確に示しています。私はそれを使用していないが、調査する価値があるかもしれない。

編集:このアプローチの問題は、代理人が保持されないため、他の場所に強い参照を保持するか、UIAlertViewへの関連参照を追加する必要があることです。このような騒ぎはそれほど価値がないかもしれません。あなたのView Controllerに余分なメソッドを追加するほうが効果的です(インタフェースの汚染を避けるために、クラス拡張のデリゲートプロトコルに準拠することができます)。

+0

ここでは[BlocksKitの最新の実装](https://github.com/pandamonia/BlocksKit/blob/master/BlocksKit/A2DynamicDelegate.h)です。 – Cfr

0

デリゲートベースのAPIでブロックを使用する場合は、いくつかのサブクラス化を行う必要があります。たとえば、UIAlertViewをサブクラス化してブロックベースのAPIを提供するPSAlertViewを参照してください。

+0

サブクラス化は理想的ではありません。 :/ – devios1

+3

これは理想的ではないだけでなく、禁止されています。[UIAlertViewクラスはそのまま使用することを目的としており、サブクラス化をサポートしていません。このクラスのビュー階層はプライベートであり、変更する必要はありません。](http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html) – vikingosegundo

+2

ブロックベースのAPIを追加するために 'UIAlertView'をサブクラス化する必要があります。たとえば、アラートビューを所有し、自身をデリゲートとして設定し、クライアントコードによって提供されるブロックを呼び出すことによってデリゲートメソッドに応答する 'MyAlert'クラスを作成できます。 – rickster

3

デリゲートプロトコルの個々のメソッドのブロックをデリゲートオブジェクトにラップするクラスを作成することもできます。詳細はthis answerを参照してください。

+0

ブロックをラップするための別のクラスを書くことは懸念の分離に役立ちますが、そうでなければかなりシンプルでなければならないオーバーヘッド/ボイラープレートが残っています。 – devios1

2

UIAlertViewにブロックサポートを追加するカテゴリを使用することを検討する必要があります。これは、使用例に対処しているようです。 UIAlertView-Blocksは他にもたくさんありますが、私のお気に入りです。

関連する問題