block的简单回调传值

时间:2021-08-10 20:43:01

由于block的火热,让我这个菜鸟也不得不多了解一下block的基本用法,虽然我之前用的是protocal代理的方式在页面之间进行的传值。但是,block的火热让我不得不来写一个demo学习下,好了废话不多说。

我所理解的block的简单用法:

首先借用大家比较熟知的一张图来解释下一般的block的样子,以及各个参数的意义。


block的简单回调传值

按照调用函数的方式调用块对象变量就可以了:
int result = myBlock(4); 

 result是 28

。。。。。。。。。

当然对上图我的理解是,block定义的一种方法,这个方法需要传入一个int类型的参数,返回值也是一个int类型的数值。而myBlock就是函数的名字,我们在c语言中调用一个函数的时候,就是myBlock(4);这样调用,而且用一个int类型的result来接收返回值。

正如c语言中的函数,如果你定义了一个函数,而没有去调用这个函数,那么这个函数就不会执行(虽然这里说的不是特别对,但是可以这样理解)。所以想让函数执行,那么我们需要在main函数中去调用我们定义的这个函数。


再看下边的例子:

  1. int global = 1000;  
  2. int main(int argc, const char * argv[])  
  3. {  
  4.     @autoreleasepool {  
  5.         void(^block)(void) = ^(void)  
  6.         {  
  7.             global++;  
  8.             NSLog(@"global:%d", global);  
  9.         };  
  10.         block();  
  11.         NSLog(@"global:%d", global);  
  12.     }  
  13.     return 0;  
  14. }  
其中global时定义的一个全局变量,而在block中去调用这个变量,并且改变它是可以的,结果都是1001;

而定一个如果是一个局部变量

  1. int local = 500;  
  2. void(^block)(void) = ^(void)  
  3. {  
  4.       local++;  
  5.     NSLog(@"local:%d", local);  
  6. };  
  7. block();  
  8. NSLog(@"local:%d", local);  
这样在block中是不可以访问到这个变量的,会报错:

block的简单回调传值

那么,如果我门想访问这个变量,并且改变它只需要在定义的时候加一个修饰符__block,然后我们就可以访问并且改变它了。


说了这么多无非想引入我要说的block的回调传值:

在两个页面间,当一个页面A和一个页面B之间,如果我想的是a中有一个button,点击这个button进入b。但是在b中有一个按钮,只有我点击b的按钮时,并且b会传值给a中的button来显示。

由于block数据类型的语法会降低整个代码的阅读性,所以常使用typedef来定义block类型。

开始,我搞不懂在哪个里边定义block的回调函数,所以只能死记了。哪个页面要传值,哪个页面来定义这个block的回调函数。

首先,我知道页面a中button显示的东西是页面b点击按钮时传递过来的,所以按照我记住的就是由页面b来定义这个block回调函数。

所以代码如下:

#import <UIKit/UIKit.h>

typedef void (^clickButtonCallBack)(NSString *str);

@interface BlockTestViewController : UIViewController

@property (copy, nonatomic) clickButtonCallBack callBack;

@end

我在b页面定义一个回调函数,也就是callBack的setter函数。首先定义个block的函数typedef void (^clickButtonCallBack)(NSString *str);让它可以传递一个字符串类型的参数,没有返回值。然后为类定义个参数,其中clickButtonCallBack作为一种类型来定义callBack变量。 一开始也不习惯这种写法,但是,只要牢记block的基本样子,还是可以对照着写出来这个回调函数的typedef void (^clickButtonCallBack)(NSString *str)然后我们回到页面b的.m文件中,在点击事件中:

- (void)clickButton{

   static int num =0;

   NSString *s = [NSStringstringWithFormat:@"点击 %d",num];

    [self.navigationControllerpopViewControllerAnimated:YES];

   if(self.callBack){

       self.callBack(s);

        num++;

    }

}

我做了简单的处理,定义个num来记录我点击的次数,其实传递的字符串就是s,也就是我点击的次数形成的字符串

页面b是由页面a push进来的,我们现在看页面a的.m中我做的处理,同样我在页面a中有一个按钮,点击按钮的事件是:

- (void)clickButton{

   __weak typeof(self) weakSelf =self;

    BlockTestViewController *blockTest = [[BlockTestViewControlleralloc] init];

    blockTest.callBack=^(NSString *str){

        [weakSelf.button setTitle:str forState:UIControlStateNormal];

    };

    [self.navigationControllerpushViewController:blockTest animated:YES];

}

其中,BlockTestViewController便是我说的页面b,

 blockTest.callBack=^(NSString *str){

        [weakSelf.button setTitle:str forState:UIControlStateNormal];

    };

这里就是我调用block的回调函数时触发的事件。str便是页面b传过来的参数

经验证传值成功。


下边是全部代码:

页面a中:

.h

#import <UIKit/UIKit.h>

@interface BlockNextViewController :UIViewController

@end

.m

#import "BlockNextViewController.h"

#import "BlockTestViewController.h"

@interface BlockNextViewController ()

@property (nonatomic,weak) UIButton *button;

@end

@implementation BlockNextViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    UIButton *testButton = [UIButtonbuttonWithType:UIButtonTypeCustom];

    testButton.frame =CGRectMake(100,400, 100, 40);

    [testButton setTitle:@"click"forState:UIControlStateNormal];

    [testButton addTarget:selfaction:@selector(clickButton)forControlEvents:UIControlEventTouchUpInside];

   _button = testButton;

    testButton.backgroundColor = [UIColorredColor];

    [self.viewaddSubview:testButton];

    // Do any additional setup after loading the view.

}


- (void)clickButton{

   __weak typeof(self) weakSelf = self;

   BlockTestViewController *blockTest = [[BlockTestViewControlleralloc] init];

    blockTest.callBack=^(NSString *str){

        [weakSelf.button setTitle:str forState:UIControlStateNormal];

    };

    [self.navigationControllerpushViewController:blockTest animated:YES];

}


页面b中:

.h

#import <UIKit/UIKit.h>

typedefvoid (^clickButtonCallBack)(NSString *str);

@interface BlockTestViewController :UIViewController

@property (copy, nonatomic) clickButtonCallBack callBack;

@end


.m

#import "BlockTestViewController.h"

@interface BlockTestViewController ()

@property (nonatomic,weak) UIButton *testButton;

@end

@implementation BlockTestViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    UIButton *testButton = [UIButtonbuttonWithType:UIButtonTypeCustom];

    testButton.frame =CGRectMake(100,400, 100, 40);

    [testButton setTitle:@"click"forState:UIControlStateNormal];

    [testButton addTarget:selfaction:@selector(clickButton)forControlEvents:UIControlEventTouchUpInside];

    testButton.backgroundColor = [UIColorredColor];

   _testButton = testButton;

    [self.viewaddSubview:testButton];

    // Do any additional setup after loading the view.

}

- (void)clickButton{

   static int num = 0;

     NSString *s = [NSStringstringWithFormat:@"点击 %d",num];

    [self.navigationControllerpopViewControllerAnimated:YES];

    if(self.callBack){

        self.callBack(s);

        num++;

    }

}