Swift
とObjective-C
で使用しているときに、完了ハンドラーとブロックの両方に混乱しています。そして、GoogleでSwift
でブロックを検索しているとき、完了ハンドラの結果が表示されています!誰かがSwift
とObjective-C
に関して完了ハンドラとブロックの違いを教えてもらえますか?
ここでは、ブロックと完了ハンドラーを簡単に区別できます。実際、両方ともブロックであり、詳細は以下を参照してください。
ブロック:
ブロックはC、Objective-C、C++に追加された言語レベルの機能であり、値のようにメソッドや関数に渡すことができるコードの個別のセグメントを作成できます。ブロックはObjective-Cオブジェクトです。つまり、NSArrayやNSDictionaryなどのコレクションに追加できます。
構文: ReturnType(^ blockName)(Parameters)例を参照:
int anInteger = 42;
void (^testBlock)(void) = ^{
NSLog(@"Integer is: %i", anInteger); // anInteger outside variables
};
// calling blocks like
testBlock();
引数付きブロック:
double (^multiplyTwoValues)(double, double) =
^(double firstValue, double secondValue) {
return firstValue * secondValue;
};
// calling with parameter
double result = multiplyTwoValues(2,4);
NSLog(@"The result is %f", result);
完了ハンドラ:
一方、完了ハンドラーは、ブロックを使用してコールバック機能を実装する方法(手法)です。
完了ハンドラーは、後でコールバックを行う必要があるメソッドにパラメーターとして渡される単純なブロック宣言にすぎません。
注:完了ハンドラーは常にメソッドの最後のパラメーターである必要があります。メソッドには必要な数の引数を指定できますが、パラメーターリストの最後の引数として完了ハンドラーを常に指定できます。
例:
- (void)beginTaskWithName:(NSString *)name completion:(void(^)(void))callback;
// calling
[self beginTaskWithName:@"MyTask" completion:^{
NSLog(@"Task completed ..");
}];
UIKit
クラスメソッドを使用したその他の例。
[self presentViewController:viewController animated:YES completion:^{
NSLog(@"xyz View Controller presented ..");
// Other code related to view controller presentation...
}];
[UIView animateWithDuration:0.5
animations:^{
// Animation-related code here...
[self.view setAlpha:0.5];
}
completion:^(BOOL finished) {
// Any completion handler related code here...
NSLog(@"Animation over..");
}];
ブロック:Obj-c
- (void)hardProcessingWithString:(NSString *)input withCompletion:(void (^)(NSString *result))block;
[object hardProcessingWithString:@"commands" withCompletion:^(NSString *result){
NSLog(result);
}];
クロージャー:Swift
func hardProcessingWithString(input: String, completion: (result: String) -> Void) {
...
completion("we finished!")
}
たとえば、完了クロージャーはここは引数文字列を取り、voidを返す関数のみです。
クロージャーは自己完結型の機能ブロックであり、コード内で受け渡し、使用できます。 Swiftのクロージャは、CおよびObjective-Cのブロック、および他のプログラミング言語のラムダに似ています。
クロージャは、Objective-Cのブロックと同様に、ネストして渡すことができるように、ファーストクラスのオブジェクトです。 Swiftでは、関数は単なるクロージャーの特殊なケースです。
要するに:完了ハンドラーは、ブロックまたはクロージャーを使用してコールバック機能を実装する方法です。ブロックとクロージャーは、値であるかのようにメソッドまたは関数に渡すことができるコードの塊です(つまり、名前を付けて渡すことができる「匿名関数」)。
これが役立つことを願っています。
最初の一歩:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
-(void)InsertUser:(NSString*)userName InsertUserLastName:(NSString*)lastName widthCompletion:(void(^)(NSString* result))callback;
@end
第二段階 :
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
-(void)InsertUser:(NSString *)userName InsertUserLastName:(NSString*)lastName widthCompletion:(void (^)(NSString* result))callback{
callback(@"User inserted successfully");
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self InsertUser:@"Ded" InsertUserLastName:@"Moroz" widthCompletion:^(NSString *result) {
NSLog(@"Result:%@",result);
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end