質問: self としてもAFNetWorkingのブロックスが実行されるときにはnilとなってしまいます...~~ Modelのインスタンス作成でミスしているだけでした。 【blocks】 View→ViewModel→Modelの流れなので...... ``` // View [_viewModel sampleMethod1:^{ [self refresh]; }]; // ViewModel - (void) sampleMethod1:(void (^) (void)) refreshView { [_model sampleMethod2:^{ refreshView(); }]; // Model - (void) sampleMethod2:(void (^) (void)) refreshView { .......... [manager POST:testAPI parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { // レスポンスをDBに登録する処理を実行 ....... // TODO: 上記DB登録処理後、Viewの更新処理を実行したい refreshView(); } failure:^(NSURLSessionDataTask *task, NSError *error) { }]; ``` } となり、VからVMに渡した処理をさらにMに渡して処理する事になり冗長な気がしました。 もっと綺麗な書き方があると思うのですが、分かりません...。 <追記2> Blocksの場合の綺麗な書き方は分かりませんが、delegateで実装できそうでした。
回答: Model内のメソッドの処理が完了したことを知らせる方法は2つほどあります。 (非同期処理が含まれている場合を書きます) * delegateを自作して、処理完了後にdelegateのメソッドを呼び出す * Block構文をメソッドの引数に持たせる 各特徴ですが、 【delegateの特徴】 * ソースのネストが少なくなる * optional指定することで、処理を譲渡される側で受け取り処理を書かなくても済み、複数箇所で利用する際にソースが荒れない * ソースを見たときに、処理を直列的に追えない 【Block構文の特徴】 * ソースの処理を直列的に追いやすい(&直列的に処理を書ける) * Model内のメソッドが減る(delegateではメソッドを必要分 追加する) * そのModelを呼び出す側で定義するオブジェクトの数が減る * ソースのネストが深くなる といったところです。 初めはどちらかの利用に統一されても良いとか思います。 私の場合は両方使いますが、 使い分けとしては、 * 連続した非同期処理ではない→delegate * 連続した非同期処理がある→Block構文 としている場合が多いかもしれません。 書き方としては、 【delegateの書き方】 Model.hを下記として ``` // デリゲートを定義 @protocol WebClientDelegate - (void)didSuccess:(NSDictionary *response); - (void)didFailure:(NSError *error); @end @interface Model : NSObject /// デリゲート先で参照するためのプロパティ @property (assign, nonatomic) id delegate; .... @end ``` Model.mを下記内のメソッドで ``` - (void)sampleMethod { [manager POST:testAPI parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { // レスポンスをDBに登録 // TODO: DB登録後、Viewの更新処理を実行したい NSDictionary *result = "何らかの結果" if([self.delegate respondsToSelector:@selector(didSuccess:)]) { [self.delegate didSuccess:result]; } } failure:^(NSURLSessionDataTask *task, NSError *error) { if([self.delegate respondsToSelector:@selector(didFailure:)]) { [self.delegate didFailure:error]; } }]; } ``` 【Block構文の書き方】 ``` - (void)sampleMethod:(void (^)(NSDictionary *response))success failure:(void (^)(NSError *error))failure { [manager POST:testAPI parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { // レスポンスをDBに登録 // TODO: DB登録後、Viewの更新処理を実行したい NSDictionary *result = "何らかの結果" success(result); } failure:^(NSURLSessionDataTask *task, NSError *error) { failure(error); }]; } ``` となります。 以上、少しでも参考になれば幸いです。