delegateの場合は、callbackがソース上で離れてしまい、コードが追いにくくなるという欠点があります。
使用するSDK等にdelegateしかない場合等にblockで実行する方法を考えてみたいと思います。
※今回はわかりやすくするため、selectorを使って解説します。
saveInBackgroundWithTarget
mBaaSのsaveInBackgroundWithTargetはselectorでcallbackのメソッドを呼び出します。
こちらの処理をblockで実行するように変更してみましょう。
処理を実行するメソッド内の処理
//testクラスのNCMBObjectを作成
NCMBObject *object = [NCMBObject objectWithClassName:@"test"];
//オブジェクトに値を設定
[object setObject:@"value" forKey:@"key"];
//データストアへの登録を実施
[object saveInBackgroundWithTarget:self selector:@selector(saveEvent:)];
- (void)saveEvent:(NSError *)error{
if (error){
//保存に失敗した場合の処理
} else {
//保存に成功した場合の処理
}
}
saveInBackgroundWithTargetをblockで実行する
プロパティ
@property(nonatomic) void (^resultBlock) (NSError *error);
処理を実行するメソッド内の処理
//testクラスのNCMBObjectを作成
NCMBObject *object = [NCMBObject objectWithClassName:@"test"];
//オブジェクトに値を設定
[object setObject:@"value" forKey:@"key"];
//データストアへの登録を実施
[self saveInBackground:object withBlock:^(NSError *error) {
if (error){
//保存に失敗した場合の処理
} else {
//保存に成功した場合の処理
}
}];
-(void)saveInBackground:(NCMBObject*)object withBlock:(void (^)(NSError *error))block {
self.resultBlock = block;
[object saveInBackgroundWithTarget:self selector:@selector(callBlock:)];
}
-(void)callBlock:(NSError *)error{
self.resultBlock(error);
}
Swiftの場合
Swiftの場合は、クロージャを設定します。
プロパティ
var resultBlock: ((Error?) -> Void)?
処理を実行するメソッド内の処理
//testクラスのNCMBObjectを作成
let object = NCMBObject.init(className: "test")
//オブジェクトに値を設定
object?.setObject("value", forKey: "key")
//データストアへの登録を実施
self.saveInBackground(object: object) { (error) in
if error != nil {
//保存に失敗した場合の処理
} else {
//保存に成功した場合の処理
}
}
func saveInBackground(object:NCMBObject?, block:((Error?) -> Void)?) -> Void {
self.resultBlock = block
object?.saveInBackground(withTarget: self, selector: #selector(callBlock(error:)))
}
func callBlock(error:Error?) -> Void {
self.resultBlock?(error)
}