• Block基本用法


    Block在iOS开发中使用频率非常高, 现总结一篇block基本用法和大家分享一下!

    声明

    • 声明格式: 返回值(^block变量名)(参数); 变量名可有可无

      void(^block1(int a)
      void(^block2)(int);
      
    • 声明blocks属性: ARC模式下用strong, MRC模式下用copy

      @property(nonatomic ,strong) void(^block)();
      

    定义

    定义格式: = ^返回值(参数), 可以使用快捷键inline, 如果没有参数或者返回值, 返回值和参数都可以省略

    • 第一种方式

      void(^block1)() = ^void(){
      NSLog(@"第一种定义方式");
      };

    • 第二种方式

      void(^block2)() = ^()
      {
      NSLog(@"第二种定义方式");
      };

    • 第三种定义方式

      void(^block3)() = ^
      {
      NSLog(@"第三种定义方式");
      };


    作用

    和函数功能相似, 保存一段代码.


    调用

    block的调用是直接去调用的.

    block();
    

    应用场景一: 保存代码

    1. 在Person类中定义一个block属性

      @property(nonatomic ,strong) void(^programmer)();
      
    2. 在tableViewController类中定义block

      Person *person1 = [[Person alloc] init];
      person.programmer = ^{
          NSLog(@"健身");
      };
      
      Person *person2 = [[Person alloc] init];
      person.programmer = ^{
          NSLog(@"读书");
      };
      
      Person *person3 = [[Person alloc] init];
      person.programmer = ^{
          NSLog(@"撸代码");
      };
      
      //添加进persons数组
      self.persons = @[person1,person2,person3];
      
    3. 在cell数据源方法中调用

      Person *person = self.persons[indexPath.row];
      
      if (Person.programmer) {
      Person.programmer();
      }
      

    应用场景二: 传值

    传值有两种情况:

    • 顺传: 上一个控制器给下一个控制器传值. 可以直接在下一个控制器中定义属性来传值.
    • 逆传: 下一个控制器给上一个控制器传值. 可以使用代理, 也可以使用block. 由于block的方便和易用性, 开发中使用block的较多些.
    1. 在下一个控制器中定义一个block属性: 参数就是下一个控制器需要传给上一个控制器的值

       @property (nonatomic, strong) void(^valueBlock)(NSString *);
      
    2. 在下一个控制器中定义block, 把值传进去

       if (_valueBlock) {
        //括号里面就是要传的值
       _valueBlock(@"这就是要传的值");
        }
      
    3. 在上一个控制器中调用block, 把参数传进来, value就是下一个控制器传给上一个控制器的值(也就是逆传的值)

       nextVC.valueBlock = ^(NSString *value){
       NSLog(@"这就是需要传的值%@",value);
        };
      


    应用场景三: block作为参数

    block作为参数, 一般在框架中使用较多.

    • 内部: 首先定义一个属性, 把block参数保存起来, 在合适的地方调用. 或者是直接在当前方法中调用用.
    • 外界: 定义block, 在block中做一些操作

    例如: 封装一个加法类

    1. 在Add类中定义一个带有block参数的方法

      @property (nonatomic, assign) int result;
      
      // int(^(int): 参数类型
      -(void)add(int(^(int))addBlock;
      
    2. 在外部controller类中定义block. 外界可以在block中随意做一些操作, 这些操作的结果都会作为参数传给内部

      Add *add = [[Add alloc] init];
      
      [add add:^int(int result){
      
              //在这里面做一些操作
              result += 10;
              return result;
       }];
      
    3. 在Add类中调用block, 可以直接调用. 也可以先保存起来, 再在合适的地方调用

      - (void)add:(int (^)(int))addBlock
      {
          _result = addBlock(_result);
           NSLog(@"%i",_result);
      
      }
      


    应用场景四: block作为返回值

    1. 在Add类定义声明一个返回值为block的方法

      @property (nonatomic, assign) int result;
      
      - (void(^)(int value))add;
      
    2. 在外部类中调用block

      Add *add = [[Add alloc] init];
      
      add.add(5);
      
    3. 在Add类中实现方法

      - (void (^)(int value))add
      {
      	return ^(int value){
      		  _result += value;
      	  };
      }
      

    Block注意问题

    1. 循环引用问题

    block会把外界的强指针强引用
    默认局部变量都是强指针

    	__weak typeof(self) weakSelf = self;
    	
    	typeof(self) strongSelf = weakSelf;
    

    2. 变量引用问题

    bock引用变量: 全局变量,静态变量,__block都是指针传递. 局部变量是值传递
    

    释义:
    默认block引用外部的局部变量,并且没有任何关键字修饰,都是值传递
    如果外部变量用__block或者static修饰,就是指针传递,外面改了,里面也会改
    只要是全局变量,Block也是指针传递

    3. 内存管理

    MRC
    block没有访问外部变量,在全局区
    如果访问了外部变量,默认block在栈中
    MRC中用copy, block才会放在堆中保存.

    释义:

    1. 如果block没有访问外部的局部变量,或者访问的变量被static修饰,或者访问全局变量,那么这个block就是全局的
    2. 如果block访问外部的局部变量,那么这个block在栈里面的.
    3. block如果想保存到堆里面,只能使用copy,不能使用retain,使用retain还是在栈里面.

    ARC
    如果访问了外部变量,默认block在堆中

    释义:

    1. 如果block访问外部的局部变量,那么这个block在堆里面的.
    2. 在ARC中,block使用strong,放在堆里面保存
    3. 能使用strong,就不要使用copy.

    内存中几个区

    全局区:保存全局变量
    常量区:保存常量
    堆:手动去管理内存,对象
    栈:基本变量,int,指针,自动管理
    方法区:保存函数


    一路伴随我的, 是对未来的无限憧憬和无数个寂静孤独的夜晚的思考和沉淀
  • 相关阅读:
    SQL CREATE INDEX 语句:如何创建索引?
    SQL DEFAULT 约束:使用方法及撤销方法解析
    SQL CHECK 约束:使用方法及撤销方法剖析
    SQL FOREIGN KEY 约束:外键的用法大全
    oracle表的管理和单行函数、多行函数、行列转换、分析函数以及集合运算
    oracle插入数据中文乱码问题
    oracle体系结构
    PL/SQL连接Oracle数据库
    SVN规范
    IDEA下 SVN 配置与使用
  • 原文地址:https://www.cnblogs.com/qinhaichuan/p/5093664.html
Copyright © 2020-2023  润新知