web-dev-qa-db-ja.com

完了ハンドラーとブロックの違い:[iOS]

SwiftObjective-Cで使用しているときに、完了ハンドラーとブロックの両方に混乱しています。そして、GoogleでSwiftでブロックを検索しているとき、完了ハンドラの結果が表示されています!誰かがSwiftObjective-Cに関して完了ハンドラとブロックの違いを教えてもらえますか?

22
shubham mishra

ここでは、ブロックと完了ハンドラーを簡単に区別できます。実際、両方ともブロックであり、詳細は以下を参照してください。

ブロック:

ブロックはC、Objective-C、C++に追加された言語レベルの機能であり、値のようにメソッドや関数に渡すことができるコードの個別のセグメントを作成できます。ブロックはObjective-Cオブジェクトです。つまり、NSArrayやNSDictionaryなどのコレクションに追加できます。

  • それらは後で実行できますが、実装されているスコープのコードが実行されているときではありません。
  • それらを使用すると、デリゲートメソッドの代わりに使用でき、1か所で記述され、多くのファイルに広がらないため、最終的にははるかにきれいで整頓されたコードが記述されます。

構文: 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..");
                     }];
31
vaibhav

ブロック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のブロック、および他のプログラミング言語のラムダに似ています。

https://developer.Apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

クロージャは、Objective-Cのブロックと同様に、ネストして渡すことができるように、ファーストクラスのオブジェクトです。 Swiftでは、関数は単なるクロージャーの特殊なケースです。

7
pedrouan

要するに:完了ハンドラーは、ブロックまたはクロージャーを使用してコールバック機能を実装する方法です。ブロックとクロージャーは、値であるかのようにメソッドまたは関数に渡すことができるコードの塊です(つまり、名前を付けて渡すことができる「匿名関数」)。

7
Axel Guilmin

これが役立つことを願っています。

最初の一歩:

#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
3
Kirill Shur