iOS中的Block

Block

使用^来声明一个block变量

void (^printBlock)(NSString *x);
    printBlock =^(NSString *str){
        NSLog(@"print:%@",str);
        };

返回值 ^block名 形参 {块内容}

概述

  • 在很多情况下,并不需要将block声明一个变量,在需要使用block的地方直接用内嵌的方式将block的内容写出来
  • 一般来说block只能读取在同一个作用于的变量而没有办法修改在block外定义的任何变量,此时若我们想这些变量能在block中被修改,就必须使用__block修饰词。如下,有修饰词的变量可写,没有__block修饰的变量只读
    • __block不能修饰长度为不定值的变量
__block int NBNum = 1;
int notNBNum = 0;

   void (^doSomeThing)(int n);
   doSomeThing = ^(int n){
       NBNum++;
       NSLog(@"%d",NBNum);
       NSLog(@"%d",notNBNum)
   };

功能

Block是一种具有匿名功能的内嵌函数,

  • 它的特性如下:

    1. 形参
    2. 有返回值
    3. lexical scope(作用域)
  • 它的使用时机:表示,简化一段代码,特别适合用于封装一些小型的task或者作为一个工作完成的callback

  • 它的优点(相对于delegatecallback):

    1. 可以直接在block中直接写入等下要执行的代码,直接将代码变成函数的参数传入函数中,这是block最常使用的地方
    2. 可以存储局部变量,传统的callback读写局部变量需要把数据封装成一个结构体,而block可以直接存取
  • 引用计数

    • 如果在blcok中引用了OC对象,那么引用计数+1;__block对引用计数无影响
  • 使用注意

    • 避免在if for循环等局部定义域内定义block并在其外面引用

Block的本质

当你定义完block之后,其实是创建了一个函数,在创建结构体的时候把函数的指针一起传给了block,所以之后可以拿出来调用

__block修饰的变量传入Blcok是地址传递,普通变量传入block是值传递

Block的三种状态:

  1. _NSConcreteGlobalBlock全局静态;

  2. _NSConcreteStackBlock栈保存,函数作用域外销毁;

  3. _NSConcreteMallocBlock堆保存,retain == 0销毁

你可能感兴趣的:(iOS中的Block)