c语言block内声明变量,iOS的内存治理和引用计数规则、Block的用法以及三种形式(stack、malloc、global)...

//将block赋值给block变量

int (^blk)(int) = ^(int){};

//将block变量赋值给block变量

int (^blk1)(int) = blk;

//两个block变量相互赋值

int (^blk2)(int);

blk2 = blk1;

//在函数参数中使用block类型变量可以向函数通报block

void func((int)(^blk)(int));

//在函数返回值中使用block可以将返回值指定为block

void func(){

return ^{return;};

}

//使用typedef界说block

typedef (int)(^blk)(int);//界说一个block,后面该block的类型就为blk

//通过block类型变量挪用block与在c语言中通常的函数执行没什么区别

blk func(blk block,int rate){

return blk(rate);

}

//这里blk截获的是Array工具的实例指针,通过这个实例指针挪用该工具的方式是完全没问题的,然则若是向Array指针赋值的话就会编译错误(可以用__block解决)

id Array = [NSMutableArray new];

void (^blk)(void) = ^{

id obj = [NSObject new];

[Array addObject:obj];

};

在block中若是需要改变被截获的外部变量的值,可以使用__block说明符(__block存储域类说明符)来解决

block代码转换为cpp代码剖析(待完善)

//block对外部变量捕捉的原理,使用cpp代码查看

//这里写一个block捕捉外部变量val的值

int val = 10;

void (^blk)(void) = ^{

printf("%d",val);

};

//block本质也是一个OC的工具,oc工具都是结构体,其中含有指向父类的isa指针

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

int val;

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _val, int flags=0) : val(_val) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

//这里使用clang -rewrite-objc将.m代码转换成.cpp代码,这里的_cself是block的自身的结构体指针,可以看到在block的函数中是将val重新创建了一个变量举行输出

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

int val = __cself->val; // bound by copy

printf("%d",val);

}

三种block的形式

NSConcreteGlobalBlock(全局Block,存放在全局区[数据区])

纪录全局变量的地方有Block语法时

Block语法的表达式中不使用应截获的自动变量时

NSConcreteStackBlock(栈Block)

除了1.中的两种情形天生的Block,其他使用Block语法发生的Block都是栈Block

NSConcreteMallocBlock(堆Block)

设置在全局区的block在变量作用域外也可以通过指针平安的接见,然则设置在栈上的block一旦其作用域竣事就会被系统接纳

Block提供了将Block和__Block变量复制到堆上的方式来解决这个问题

复制到堆上的block将类工具NSMallocBlock赋值给isa指针

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _val, int flags=0) : val(_val) {

//注重这里就是讲isa指针指向堆Block

impl.isa = &_NSConcreteStackBlock;

}

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值