zoukankan      html  css  js  c++  java
  • OC中的__block修饰符

    __block修饰符

    __block可以用于解决block内部无法修改auto变量值的问题, __block不能修饰全局变量、静态变量

    写下面的block代码:

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            __block int age = 0;
            void(^test)(void) = ^{
                age = 10;
                NSLog(@"%d",age);
            };
            test();
        }
        return 0;
    }

    经过xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m转为C++代码后,

    关键代码如下:

    static struct __test1_block_desc_0 {
      size_t reserved;
      size_t Block_size;
    } __test1_block_desc_0_DATA = { 0, sizeof(struct __test1_block_impl_0)};
    void test1() {
    
        block = ((void (*)())&__test1_block_impl_0((void *)__test1_block_func_0, &__test1_block_desc_0_DATA));
    
    }
    
    struct __Block_byref_age_0 {
      void *__isa;
    __Block_byref_age_0 *__forwarding;
     int __flags;
     int __size;
     int age;
    };
    
    struct __main_block_impl_0 {
      struct __block_impl impl;
      struct __main_block_desc_0* Desc;
      __Block_byref_age_0 *age; // by ref
      __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_age_0 *_age, int flags=0) : age(_age->__forwarding) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
      }
    };

    变量在被__block修饰后,会被包装成__Block_byref_变量_0的一个对象,该变量会被copy到堆上。

    当block在栈上时,并不会对__block变量产生强引用

    当block被copy到堆时,会调用block内部的copy。copy函数内部会调用_Block_object_assign函数

    _Block_object_assign函数会对__block变量形成强引用

    NSObject *object = [[NSObject alloc] init];
    __block NSObject *tempObject = object;
    void(^test)(void) = ^{
       NSLog(@"%p",tempObject);
    }; test();

    转为C++之后,会进行强引用:

    struct __Block_byref_tempObject_0 {
      void *__isa;
    __Block_byref_tempObject_0 *__forwarding;
     int __flags;
     int __size;
     void (*__Block_byref_id_object_copy)(void*, void*);
     void (*__Block_byref_id_object_dispose)(void*);
     NSObject *__strong tempObject;
    };

    进行__weak修饰之后,

    NSObject *object = [[NSObject alloc] init];
     __block __weak NSObject *tempObject = object;
     void(^test)(void) = ^{
          NSLog(@"%p",tempObject);
     };
     test();

    转为C++代码:

    struct __Block_byref_tempObject_0 {
      void *__isa;
    __Block_byref_tempObject_0 *__forwarding;
     int __flags;
     int __size;
     void (*__Block_byref_id_object_copy)(void*, void*);
     void (*__Block_byref_id_object_dispose)(void*);
     NSObject *__weak tempObject;
    };

    当block从堆中移除时,会调用block内部的dispose函数,dispose函数内部会调用_Block_object_dispose函数

    _Block_object_dispose函数会自动释放引用的__block变量(realse)

  • 相关阅读:
    python中的反射
    ZOJ 3827 Information Entropy 水
    我的软考之路(七)——数据结构与算法(5)之查找
    nginx.conf 集群完整配置
    恼人的函数指针(二)
    C语言100个经典的算法
    spring事务心得积累
    Vue报错:OPTIONS 405 Method Not Allowed以及CORS跨域错误
    IDA脚本dump内存的示例
    lightProxy
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/14146811.html
Copyright © 2011-2022 走看看