Block小结

Block小结

一、block的类型

  • GlobalBlock
  • StackBlock
  • MallocBlock

二、生成条件

GlobalBlcok:
如果一个block没有引用任何外部变量,此时block是一个GlobalBlock

StackBlock:
相对于GlobalBlock,如果一个block内部引用了外部变量
MRC:此时的block会是一个GlobalBlock
ARC:此时的block会是一个MallocBlock
Tips: ARC下会对GlobalBlock做优化,当创建一个block时会默认返回一个MallocBlock。但是在ARC中当block作为函数参数时,此时block是一个GlobalBlock。

MallocBlock:
MRC:对StackBlock copy得到MallocBlock
ARC:默认创建的Block,除了GlobalBlock都是MallocBlock

三、block的copy、retain、release操作

这些操作都是在MRC情况下

  • 对block进行copy、retain、release都不会改变retainCount,retainCount始终是1
  • GlobalBlock的retain、copy、release都无效
  • StackBlock的retain、release操作无效,StackBlock在函数返回后,block内存将会被回收
  • MallocBlock 支持retain、release,是retainCount始终是1

四、block对不同类型变量的存取

  1. 基本类型
    局部变量,在block中只读。block__定义__时,copy变量的值,在block中作为常量使用;static变量、全部变量,在内存中的位置是固定的,block在读取时会直接从内存中读出,获取到最新的值;被__block修饰的变量,基本类型的block变量等效于static变量;block被另一个block使用时,另一个block被copy到堆上时,被使用的block也会被copy。但是作为参数的block是不会copy的

  2. 引用类型
    局变量和static变量在内存中的位置是确定的,所以不会retain变量,_instanceObj在block中使用时,不会retain _instanceObj本身,但是会retain self,local在block中 时,会retain对象,增加引用计数;block obj在block copy时也不会retain

附带几个block的坑,分析在MRC和在ARC情况下都是否能执行

题目1.

void exampleA()
{
  char a = 'A';
  ^{
     printf("%c\n",a);
   }();
}

题目2.

void exampleB_addBlockToArray(NSMutableArray *array)
 {
  char b = 'B';
  [array addObject:^{
     printf("%c\n",b);
  }];
  }

void exampleB()
{
  NSMutableArray *array = [NSMutableArray array];
  exampleB_addBlockToArray(array);
  void(^block)() = [array objectAtIndex:0];
  block();
}

题目3.

void exampleC_addBlockToArray(NSMutableArray *array)
{
 [array addObject:^{
   printf("C\n");
  }];
}

void exampleC()
{
  NSMutableArray *array = [NSMutableArray array];
  exampleC_addBlockToArray(array);
  void(^block)() = [array objectAtIndex:0];
  block();
}

题目4.

typedef void(^dBlock)();

dBlock exampleD_getBlock() {
 chard = 'D';
 return^{
   printf("%c\n",d);
  };
}

void exampleD()
{
 exampleD_getBlock()();
}

题目5.

typedef void(^eBlock)();

eBlock exampleE_getBlock() {
 chare = 'E';
 void(^block)() = ^{
   printf("%c\n",e);
   };
 returnblock;
}

void exampleE()
{
 eBlock block = exampleE_getBlock();
 block();
}

答案是:1、3 在MRC和ARC情况下都能使用 2、4、5 只有在ARC情况下才能使用
提示:stackBlock 会在block返回后被释放,global则不需要关系释放的问题,mallocBlock会手动释放或arc自动管理,在arc情况下,不作为参数的stackBlock会被自动创建为mallocBlock

文章参考:https://www.zybuluo.com/MicroCai/note/57603
http://blog.parse.com/learn/engineering/objective-c-blocks-quiz/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值