美文网首页IOS 拾遗程序员iOS进阶之路
(三)Block之截获变量和对象

(三)Block之截获变量和对象

作者: madaoCN | 来源:发表于2017-10-21 19:28 被阅读22次

相关文章


捕获自动变量

int i = 0;//自动变量
void (^blk)() = ^() {
    printf("%d", i);
};
blk();

经过转换代码后的部分源代码

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  int i; //需要注意
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _i, int flags=0) : i(_i) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
// Block方法指针
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
        int i = __cself->i; // bound by copy 需要注意
        printf("%d", i);
 }
// 构造函数的调用
__main_block_impl_0 blk = __main_block_impl_0(
                            __main_block_func_0, 
                            &__main_block_desc_0_DATA, 
                            i);

可见,自动变量i被追加到了__main_block_impl_0结构体中(如果Block语法中没有使用自动变量,则不会被追加)
在构造函数调用时候自动变量i也被当做参数传入了构造方法中
那么可知__main_block_impl_0被初始化为如下:

impl.isa = &_NSConcreteStackBlock;
impl.Flags = 0;
impl.FuncPtr = __main_block_func_0;
Desc = & __main_block_desc_0_DATA;
i = 0;

然后,将关注点放在Block方法指针上

 int i = __cself->i; 

执行Block语法时候,将__main_block_impl_0捕获的自动变量,被赋值给了内部新定义的变量

总的来说 “截获自动变量”意味着 将即将使用的变量保存到Block结构体实例中

捕获对象

id array = [[NSMutableArray alloc] init];
void (^blk)() = ^() {
     [array addObject:@"obj"];
     printf("%lu", (unsigned long)[array count]);
};
blk();

经过转换代码后的部分源代码

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __strong id array; //注意这里
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __strong id _array, int flags=0) : array(_array) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
        __strong id array = __cself->array; // bound by copy
       [array addObject:@"obj"];
       printf("%lu", (unsigned long)[array count]);
}

static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) 
{
        _Block_object_assign((void*)&dst->array, 
                                     (void*)src->array,       
                                     3/*BLOCK_FIELD_IS_OBJECT*/);
}

static void __main_block_dispose_0(struct __main_block_impl_0*src)
 {  
        _Block_object_dispose((void*)src->array, 
                               3/*BLOCK_FIELD_IS_OBJECT*/);
}

static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
  void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);//注意这里
  void (*dispose)(struct __main_block_impl_0*);//注意这里
} 
__main_block_desc_0_DATA =
 {
    0,
    sizeof(struct __main_block_impl_0), 
    __main_block_copy_0, 
    __main_block_dispose_0
};
  • __main_block_impl_0内部以__strong id array;形式捕获了对象
    那我们知道,c语言在Object中是不支持__strong修饰符的,那么是如何对其内存管理的呢?
    我们注意到,转换后的代码多出了两个方法__main_block_copy_0__main_block_dispose_0
    前者于OC的retain方法 ,将捕获的对象赋值给另一个对象结构体的的成员变量中
    后者相当于 release方法,将结构体实例中捕获的变量释放

  • 内存管理方法调用时机

函数 调用时机
__main_block_copy_0 Block从栈复制到堆
__main_block_dispose_0 堆上Block被废弃

那么什么时候栈会被复制到堆呢?

  • 调用copy方法
  • Block作为返回值(超出作用域)
  • 将Block赋值给id 或者 __strong类型变量
  • 在带有usingBlock的Cocoa方法或者GCD的API中传递Block时候

相关文章

  • Objective-C的Block实质与实现探究 part-6

    Block使用__block�变量,且该变量为对象的情况 转换为C++: 虽然与截获对象时和使用__block变量...

  • (三)Block之截获变量和对象

    相关文章 (一)Block的实质初探 (二)Block之存储域 NSConcreteStackBlock,NSCo...

  • iOS知识整理-Block

    Block是将函数及其执行上下文封装起来的对象 变量截获 局部变量截获 是值截获 〜局部静态变量截获 是指针截获 ...

  • Block

    一、Block本质 二、 BlocK截获变量 三、__block 修饰变量 四、Block内存管理 五、Block...

  • Block(匿名函数)

    一、语法格式 二、截获自动变量值和__block修饰符 block的自动变量截获只针对block中使用的自动变量。...

  • 2022-11-17 07Block相关

    什么是block 1.Block是将函数及其执行上下文封装起来的对象 截获变量对不同类型的变量截获不同 1.对于基...

  • Objective-C的Block实质与实现探究 part-3

    Block截获静态变量的情况 要使得Block能够改变值的第一种办法,是使用静态变量、静态全局变量、全局变量三种之...

  • iOS-面试

    面试知识点 block 什么是block是将函数及其上下文封装起来的对象 block的截获变量对不同变量类型分别是...

  • 2022-04-13 block笔记

    什么是block 什么是block调用 block截获变量 __block修饰符用在什么场景,__block变量_...

  • __block

    __ block Block中所使用的被截获自动变量就如“带有自动变量值的匿名函数”所说,仅截获自动变量的值,Bl...

网友评论

    本文标题:(三)Block之截获变量和对象

    本文链接:https://www.haomeiwen.com/subject/lyghuxtx.html