iOS学习之路01 - Block

Block
  • 创建的三种形式
    • 没有参数,没有返回值的block

      void (^myBlock1))() = ^{};

      myBlock1();

    • 有参数,没有返回值的block

      void (^myBlock2)(int a) = ^(int a){};

      myBlock2();

       

      ^(int a){}; 也可写作 ^void(int a){};

    • 有参数,有返回值的block

      int (^myBlock3)(int a, int b) = ^(int a, int b){};

      int a = myBlock3(1, 2);

      类中@implementation 中可以书写C语言函数,并可以被调用

  • 将block作为参数或者返回值,利用typedef

    typedef void(^TestBlock)(int a, int b);

    • 作为参数

      - (void) method_testBlock1: (TestBlock)block{

          block(100, 200); //最后调用这个代码块去执行

      };

    • 作为返回值

      - (TestBlock) method_testBlock2{

          return ^void(int a, int b){

              NSLog(@" method_testBlock2 a*b = %d", a*b);

      };

      };

    • 注意:见到 ^ 符号则要写方法体,见到返回值类型则只需调用执行
  • block的应用场景
    • 作为方法参数
    • 作为属性使用,同委托一样可以进行类与类之间的通讯
    • 作为函数使用
  • 对外部变量的使用或改变
    • 使用局部变量
      • block内部使用局部变量,会将变量值拷贝一份到block中,那么block的变量就不再是原来的变量,已变成了呀un来变量的副本,所以外部修改不会影响block内部的值
      • 使用__block修饰的变量,block内部使用时不会进行拷贝,使用的还是同一个变量,所以在外部修改后会影响block内部的值
    • 使用全局变量
      • block内部要对全局变量修改就不需要使用__block来修饰了
  • iOS 堆(heap)和栈(stack)的理解
    • 栈区:由编译器自动分配释放,存放对象指针、局部变量、局部参数。其操作方式类似数据结构中的栈
    • 堆区:一般由程序员分配释放,存放对象指针指向的内容
    • 栈区中存储的对象内存长度固定不可修改,堆区中的对象内存长度可变
    • 全局区、静态区:存放全局变量、静态变量
    • 常量区:存放常量
  • 内存管理
    • block有三种存储位置,__NSGlobalBlock(全局区block,类似于函数)、__NSStackBlock__(栈区的block),当block使用了局部变量、全局变量……就会形成栈区的block、③__NSMallocBlock__(堆区的block)当block进行copy操作,是将block从栈区拷贝到堆区,堆区的block需要管理内存
    • 在block中使用了对象(未修改对象)时,Block_copy(block)或者[block copy]只会使局部对象引用计数+1、全局对象不做任何处理、(对象属性、实例对象)所在的对象(self)引用计数+1,最终目的是让block持有这些对象
  • 解决循环引用
    • __block修饰符:①被__block修饰的对象可在block进行copy时,其自身的引用计数不会被+1。②被__block修饰的元素可以在block中被修饰
    • 在A类中有一个属性block,类型是代码块。然A类中又有一个实例方法,方法中对属性block赋值,然block被赋予的代码块又使用self,并对A类中的另一个NSString *类型的属性str赋值了,这就导致了相互引用

      解决方案:

      • 在MRC(手动内存管理)中
        • __block typeof(self) blockSelf = self;
        • __block A *a = self;
      • 在ARC(自动内存管理)中
        • __weak typeof(self)weakSelf = self;
        • 此处必须使用__weak而不能使用__block,因为使用__block去修饰,weakSelf(self)的引用计数+1。在当前对象的实例方法的block中,使用当前对象的str属性时,因属性本省就被存储,在堆区中,所以不需要去copy,又因是copy去修饰这个block类型的属性,所以当不需要copy时,__block = [block copy]会选择浅赋值,即只传指针,不对内容进行copy,也就是当前对象的str属性未被copy
        • 注意:weakSelf.str = @"……..";这当中weakSelf是被使用了,str则是去修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值