您好,欢迎来到二三四教育网。
搜索
您的当前位置:首页iOS block的用法举例

iOS block的用法举例

来源:二三四教育网

一、Block的几种写法

1、有返回值、有参数列表

先介绍一下Block语法的书写,首先来看一个完整的Block:

    int (^ExistReturnValueWithExistParameterBlock)(int num);
    
//   “^”这个符号表示这是一个Block;
//    返回值:int表示返回值类型
//    变量名:ExistReturnValueWithExistParameterBlock
//    参数列表:(int num)这个括号中是Block的参数
    
    ExistReturnValueWithExistParameterBlock = ^ int(int num){    
         NSLog(@"有参数列表,参数为:%d,有返回值,返回值为:%d",num,300+num);
         return 300+num;
    };
    
    ExistReturnValueWithExistParameterBlock(500);

    打印结果:有参数列表,参数为:500,有返回值,返回值为:800

也可以省略不写Block的返回值,例如以下写法:

    int (^ExistReturnValueWithExistParameterBlock)(int num);

    ExistReturnValueWithExistParameterBlock = ^(int num){
        return 300+num;
    };

    ExistReturnValueWithExistParameterBlock(500);

2、没有返回值,没有参数列表

完整写法①:

    void (^NoReturnValueWithNoParameterBlock)(void) = ^void(void) {
        NSLog(@"没有返回值,没有参数列表");
    };
    
    NoReturnValueWithNoParameterBlock();

    打印结果:没有返回值,没有参数列表

完整写法②:

    void (^NoReturnValueWithNoParameterBlock)(void);

    NoReturnValueWithNoParameterBlock = ^void(void) {
        NSLog(@"没有返回值,没有参数列表");
    };

    NoReturnValueWithNoParameterBlock();

简略写法①:

    void (^NoReturnValueWithNoParameterBlock)() = ^ {
        NSLog(@"没有返回值,没有参数列表");
    };

    NoReturnValueWithNoParameterBlock();

简略写法②:

    void (^NoReturnValueWithNoParameterBlock)();

    NoReturnValueWithNoParameterBlock = ^ {
        NSLog(@"没有返回值,没有参数列表");
    };
    
    NoReturnValueWithNoParameterBlock();

3、没有返回值,有参数列表

完整写法①:

   void(^ExistParameterBlock)(int num) = ^(int num){
        NSLog(@"没有返回值,有参数列表,参数为:%d",num);
    };

    ExistParameterBlock(100);

    打印结果:没有返回值,有参数列表,参数为:100

完整写法②:

    void(^ExistParameterBlock)(int num);
    
    ExistParameterBlock = ^(int num){
         NSLog(@"没有返回值,有参数列表,参数为:%d",num);
    };

    ExistParameterBlock(100);

4、有返回值、没有参数列表

完整写法:

    int(^ExistReturnValueBlock)();
    
    ExistReturnValueBlock = ^ int{
        return 200;
    };
    
    NSLog(@"没有参数列表,有返回值,返回值为:%d",ExistReturnValueBlock());

    打印结果:没有参数列表,有返回值,返回值为:200

二、Block改变外部变量的值

1、非集合对象

   int value = 11;
   void (^changeValueBlock)() = ^{
      value = 33;
   };

这段代码编译出错,编译器提示的大概就是不能在Block中改变变量的值。因为在Block中截获了变量的瞬间值以后就不能再改变变量的值,如果想要在Block中改变变量的值,那么我们只需要在变量声明的时候加上__block修饰符。

如下:

    __block int value = 11;
    NSLog(@"value改变之前:%d", value);
    void (^changeValueBlock)() = ^{
        value = 33;
    };
    changeValueBlock();
    NSLog(@"value改变之后:%d", value);

    打印结果:value改变之前:11
    打印结果:value改变之后:33

2、集合对象

和非集合对象不一样。对于集合对象,因为我们只是对截获的变量进行了操作,而没有进行赋值,所以对于截获变量,可以进行操作而不可以进行赋值。

    NSMutableArray *array = [[NSMutableArray alloc]init];
    NSLog(@"array改变之前:%@", array);
    void (^changeArrayBlock)() = ^{
        [array addObject:@"block"];
    };
    changeArrayBlock();
    NSLog(@"array改变之后:%@", array);

    打印结果:array改变之前:( )
    打印结果:array改变之后:( block, )

三、Block当作函数参数

具体代码如下:

//
//  SecondViewController.m
//

#import "SecondViewController.h"

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

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //Block当作函数参数
    [self testBlockMethod:^(NSString *str) {
        NSLog(@"%@",str);
    }];
}

- (void)testBlockMethod:(ParameterBlock)block {
    block(@"测试block为函数参数");
}

@end

四、Block逆向传值

在APP页面跳转过程,如果A 页面--> B页面是正向的话,那么我们把B页面的值传给A就叫做 反向传值、逆向传值(或者叫做回调)。
首先建立两个控制器HomeViewController(A)和TestViewController(B),HomeViewController(A) 跳转到TestViewController(B) 。HomeViewController(A)作为捕获方,TestViewController(B)作为传值方。

1、传值方---TestViewController(B)

TestViewController.h文件

//
//  TestViewController.h
//  
//  谁传值,谁就写block

#import <UIKit/UIKit.h>

typedef void(^TransmitBlock)(NSString *title);

@interface TestViewController : UIViewController

@property (nonatomic, copy) TransmitBlock block;

@end

TestViewController.m文件

//
//  TestViewController.m
//

#import "TestViewController.h"

@interface TestViewController ()

@property (nonatomic, strong) UIButton *testBtn;

@end

@implementation TestViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _testBtn = [[UIButton alloc]initWithFrame:CGRectMake(200, 200, 55, 55)];
    [self.view addSubview:_testBtn];
    _testBtn.backgroundColor = [UIColor redColor];
    [_testBtn setTitle:@"点击" forState:UIControlStateNormal];
    [_testBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [_testBtn addTarget:self action:@selector(clickedBtn) forControlEvents:UIControlEventTouchUpInside];
}

- (void)clickedBtn {
    self.block(@"block测试");
}

@end

2、捕获方---HomeViewController(A)

HomeViewController.m文件

//
//  HomeViewController.m
//

#import "HomeViewController.h"
#import "TestViewController.h"

@interface HomeViewController ()

@property (nonatomic, strong) UILabel *titleLab;
@property (nonatomic, strong) UIButton *clickBtn;

@end

@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.titleLab = [[UILabel alloc]initWithFrame:CGRectMake(200, 100, 100, 30)];
    [self.view addSubview:self.titleLab];
    self.titleLab.backgroundColor = [UIColor yellowColor];
    self.titleLab.textColor = [UIColor blueColor];
    self.titleLab.font = [UIFont systemFontOfSize:20.0];

    self.clickBtn = [[UIButton alloc]initWithFrame:CGRectMake(200, 200, 55, 55)];
    [self.view addSubview:self.clickBtn];
    self.clickBtn.backgroundColor = [UIColor redColor];
    [self.clickBtn setTitle:@"跳转" forState:UIControlStateNormal];
    [self.clickBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [self.clickBtn addTarget:self action:@selector(jumpToTestVC) forControlEvents:UIControlEventTouchUpInside];
}

- (void)jumpToTestVC {
    
    TestViewController *testVC = [[TestViewController alloc]init];
    
    __weak typeof(self) weakself = self;
    
    testVC.block = ^(NSString *title){
        
        __strong typeof(weakself) strongSelf = weakself;
        
        strongSelf.titleLab.text = title;
    };
    
    // weakSelf是为了block不持有self,避免循环引用,而再声明一个strongSelf是因为一旦进入block执行,就不允许self在这个执行过程中释放。block执行完后这个strongSelf会自动释放,没有循环引用问题。
    [self.navigationController pushViewController:testVC animated:YES];
}
@end

Copyright © 2019- how234.cn 版权所有 赣ICP备2023008801号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务