首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Blocks笔记(5)

Blocks笔记(5)

block的内存管理

    block截获对象

    typedef void (^myBlock)(id obj);
    myBlock block;
    - (IBAction)test_6id)sender {
        [self captureObject];
        block([[NSObject alloc]init]);
        block([[NSObject alloc]init]);
        block([[NSObject alloc]init]);
    }
    //截获对象
    - (void)captureObject {
        id array = [[NSMutableArray alloc] init];
        block = [^(id obj){
            [array addObjectbj];
            NSLog(@"array count = %ld", [array count]);
        } copy];
    }

翻译代码:

    struct __main_block_impl_0 {
        struct __block_impl impl;
        struct __main_block_desc_0 *Desc;
        id __strong array;
     
        __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, id __strong _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, id obj) {
        id __strong array = __cself->array;
        [array addObjectbj];
        NSLog(@"array count = %ld", [array count]);
    }
     
    static void __main_block_copy_0(struct __main_block_impl_0 *dst, __main_block_impl_0 *src) {
        _Block_object_assign(&dst->array, src->array, BLOCK_FIELD_IS_OBJECT);
    }
     
    static void __main_block_dispose_0(struct __main_block_impl_0 *src) {
        _Block_object_dispose(src->array, BLOCK_FIELD_IS_OBJECT);
    }
     
    struct static struct __main_block_desc_0 {
        unsigned long reserved;
        unsigned long 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
                                 };
     
    /* Block literal and executing the Block */
    blk_t blk;
    {
        id __strong array = [[NSMutableArray alloc] init];
        blk = &__main_block_impl_0(__main_block_func_0,
                                   &__main_block_desc_0_DATA,
                                   array,
                                   0x22000000);
        blk = [blk copy];
    }
    (*blk->impl.FuncPtr)(blk, [[NSObject alloc] init]);
    (*blk->impl.FuncPtr)(blk, [[NSObject alloc] init]);
    (*blk->impl.FuncPtr)(blk, [[NSObject alloc] init]);
     总结block的内存管理:
    1.栈上的block copy到堆上时,通过copy方法,__main_block_copy_0函数使用_Block_object_assign函数将变量array对象赋值给block结构体成员变量并持有该对象; _Block_object_assign调用相当于retain实例方法的函数,而__main_block_dispose_0函数使用_Block_object_dispose函数释放赋值在结构体成员变量array中的对象;
    以下情形,block会从栈copy到堆:

        .当 block 调用 copy 方法时,如果 block 在栈上,会被拷贝到堆上;
        2).当 block 作为函数返回值返回时,编译器自动将 block 作为 _Block_copy 函数,效果等同于 block 直接调用 copy 方法;
        3).当 block 被赋值给 __strong id 类型的对象或 block 的成员变量时,编译器自动将 block 作为 _Block_copy 函数,效果等同于 block 直接调用 copy 方法(block用copy修饰的原因);
        4).当 block 作为参数被传入方法名带有 usingBlock 的 Cocoa Framework 方法或 GCD 的 API 时。这些方法会在内部对传递进来的 block 调用 copy 或 _Block_copy 进行拷贝;

2.栈区的block(_NSConcreteStackBlock)在作用域结束后就会被废弃;
3.全局的block(_NSConcreteGlobalBlock)的实例是在数据区域,全局都能访问到,不依赖执行时的状态,因此retain、copy、release操作都无效;
返回列表