学习block时的一些笔记

1.完整写法

void(^ blockName)(arg)=void^(arg){};

2.block 可以使用截取到的自动变量,但是不允许修改重新赋值。

例:

int m=3;

    char* str1="str1";

    void(^block1)(void)=^(){

      

        NSLog(@"%d,%s",m,str1);

    };

    m=6;

    str1="变化";

    block1();

OUTPUT:3,str1

 

若要修改自动变量的值必须添加__block

 

block以及截取自动变量的本质

使用clang -rewrite-objc 命令转化上面的代码

/**

 __block_impl 结构体

 */

struct __block_impl {

    void *isa;

    int Flags;

    int Reserved;

    void *FuncPtr;

};

 

/**

 __main_block_impl_0结构体  

 */

struct __main_block_impl_0 {

  //__block_impl 结构体

  struct __block_impl impl;

  //__main_block_desc_0 结构体

  struct __main_block_desc_0* Desc;

  int m;

  char *str1;

   

  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _m, char *_str1, int flags=0) : m(_m), str1(_str1) {

    //_NSConcreteStackBlock 用于初始化__block_impl 结构体的isa成员 表明该block类型为NSConcreteStackBlock

    impl.isa = &_NSConcreteStackBlock;

    impl.Flags = flags;

    impl.FuncPtr = fp;

    Desc = desc;

  }

};

 

/**

 1.变换后的block1 被作为简单的C语言函数来处理

 2.函数中的__cself 相当于OC中的self 这里指代__main_block_impl_0结构体的指针 

 ^(){

 int n=m+3;

 printf("%d,%s",m,str1);

 };

  */

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

  int m = __cself->m; // bound by copy 自动变量被保存到Block的结构体实例中。需要注意的是Block中不能直接使用C语言数据类型的自动变量,原因是C语言不允许这种操作

  char *str1 = __cself->str1; // bound by copy

        int n=m+3;

        printf("%d,%s",m,str1);

 

    }

 

/**

 __main_block_desc_0 结构体

 */

static struct __main_block_desc_0 {

  size_t reserved;

  size_t Block_size;

} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

 

int main(int argc, char * argv[]) {

 

    int m=3;

    char* str1="str1";

    /*

     void(^block1)(void)=^(){

    

     int n=m+3;

     printf("%d,%s",m,str1);

    

     };

     */

    void(*block1)(void)=((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, m, str1));

 

    m=6;

    str1="变化";

    ((void (*)(__block_impl *))((__block_impl *)block1)->FuncPtr)((__block_impl *)block1);

 

}

_ _block 修饰的变量 本质

例:__block int  m=3;此时m会被转化为__Block_byref_m_0结构体

struct __Block_byref_m_0 {

  void *__isa;

  __Block_byref_m_0 *__forwarding; (指向m:__Block_byref_m_0本身)

 int __flags;

 int __size;

 int m;// m=3

};

__Block_byref_m_0 *__forwarding;//持有指向该实例自身的指针,通过成员变量__forwarding访问成员变量val

解决循环引用问题
 

__weak typeof(_tom) weak = _tom;

   

    _tom.block = ^{

     

        __strong typeof(weak) strong = weak;

       

    };

__weak : 打破强引用链 即_tom对象强引用block对象,block对象强引用_tom对象

 

__strong:在block中声明了一个局部变量,暂时“强引用”_tom对象,由于block并不会强引用block内部声明的__strong修饰的局部变量。所以这样即保证了在block调用时_tom对象存在又不会造成循环引用。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值