Object-C中的Block理解

闭包是一个函数(或者指向函数的指针) +  函数执行的非局部变量。

闭包允许一个函数访问该函数运行上下文中的变量,甚至可以访问不用运行上文中的变量。

block是OC对闭包的实现。

1、block可以访问局部变量,全局变量,即使是static。

2、block中变量修改情况:

      1)对于block外部的变量引用,默认是将其复制到数据结构中实现访问的,通过block进行闭包的变量是const的,不能直接修改这些变量。

      2)__block修饰外部变量引用,block复制其引用地址来实现访问。

3、block结构体定义如下:

   struct Block_layout{

        void *isa;//指向表明该block类型的类

         int flags;//按bit位标示一些的block的附加信息,比如判断block类型、判断block引用计数、判断block是否需要执行辅助函数等。

         int reserved;//保留变量

         void (* invoke)(void *,...);//函数指针,执行具体的block实现的函数调用地址。

         struct Block_descriptor  *descriptor;//block的附加信息,比如保留变量数,block的大小,进行copy活dispose得辅助函数指针。

         /*Imported variables*/ //因为block有比暴行,所以可以访问block外部的局部变量。这些variables就是复制到结构体中的外部局部变量或变量的地址。 

};

struct Block_descriptor{

unsigned long int reserved;

unsigned long int size;

void  (*copy)(void *dst, void *src);

void  (*dispose)(void *);

};

4、block的类型

    block几种不同的类型,每个类型都有对应的类,isa指针就是指向这个类。

        NSConcreteGlobalBlock: 全局的静态block,不会访问任何外部变量,不会涉及到任何拷贝。此类型的block要么是空block,要么不访问任何外部的block。

  NSConcreteStackBlock: 保存在栈中的block,当函数返回时被销毁。此类型的block又闭包行为,也就是有访问外部变量的能力,且只有一次执行,执行一次就被清除栈了,无法多次使用。

NSConcreteMallocBlock: 保存在队中的block,引用计数为0时被销毁。此类型的block又闭包行为,且需要被多次执行,当需要多次执行时,会把该block从栈中复制到堆中,以供多次执行。

ARC与非ARC三种类型需要注意点事项:

1)只要不访问外部变量====》NSConcreatGlobalBlock

2)   ARC下不存在NSConcreatStatckBlock,会自动拷贝到堆上

3)在非ARC下需要注意NSConcreatStatckBlock的生命周期

NSConcreatGlobalBolck 在ARC与非ARC下没有区别

NSConcreatStatckBlock 在ARC下会被转化为NSConcreatMallocBlock(由栈到堆) ,非ARC下不变

NSconcreatMallockBock 在ARC与非ARC下没有区别

5、block执行原理


int main()

{

__block int i = 1024;

int j = 1;

void (^ blc)(void);

blk = ^{printf("i:%d, j:%d, &i=%p, &j:%p",i,j,&i,&j);};

}

=======>>>

int main()

{

__attribute__((__blocks__(byref))) __Block_byref_i_0  i = {(void*)0,(__Block_byref_i_0,_main_block_disponse_0)};

 int j = 1;

void (*blk)(void);

blk = (void (*)())&__main_block_impl_0((void *)__main_block_func_0,&__main_block_desc_0_DATA,j,(__Block_byref_i_0 *)&i,)

blk();

等价于(void (*) (__block_impl *)) ((__block_impl *)blk) -->FuncPtr)((__block_impl *)blk);

}

    block是一个指向__main_block_impl_0结构体指针,初始化后被强转为函数指针,其中包含的__block_impl是一个公共实现。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值