こんにちは、JAGA(@ja_gaimopotato)です。
デリゲートメソッドの結果を受け取り、Blockとして非同期で返したいことがあります。
デリゲートメソッドが多いクラスの見通しをよくするためのラッパークラスを作るような場合です。
ぼくのアプローチは、だいたいこの2つ方法です。
どんな方法があるのか。
デリゲートメソッドに繋がる一連の呼び出しの最初のメソッドで、引数にBlockを取得しておいて、それをラッパークラスで保持しておき、デリゲートメソッドを呼び出すタイミングでそのBlockを実行する。
コードにするとこんな感じですか。
@property (copy,nonatomic,readwrite)void (^myAction)();
- (void)startWithBlock:(void(^)())action{
// ラッパークラスなので、デリゲートメソッドでアクションを実行するために保持
_myAction = action;
// 何かアクションを開始して、デリゲートで受け取る
something.delegate = self;
[something action];
}
- (void)delegateMethod{
_myAction();
}
もう1つが、デリゲートメソッドが複数あり、それらが複数回呼ばれることを前提に、逐次実行する。
進捗を取得する必要がある場合ですね。
@property (copy,nonatomic,readwrite)void (^myAction)(NSInteger progress);
@property (nonatomic,readwrite)NSInteger counter;
- (void)startWithBlock:(void(^)())action{
// ラッパークラスなので、デリゲートメソッドでアクションを実行するために保持
_myAction = action;
// カウンターなどでBlockが呼び出されるタイミングを制御する
counter = 0;
something.count = 10;
// 何かアクションを開始して、デリゲートで受け取る
something.delegate = self;
[something action];
}
// 何回か呼ばれる
- (void)delegateMethodA{
counter += 1;
[self doAction];
}
// 何回か呼ばれる
- (void)delegateMethodB{
counter += 1;
[self doAction];
}
- (void)doAction{
NSInteger progress = counter / something.count;
_myAction(progress);
}
さいごに
AVFoundationを使うときなどは、ラッパークラスでまとめる方が使いやすいです。
カメラアプリを作っているときに多用しました。
もっと良い方法があるかもしれませんので、色々と研究したいですね。