【Objective-C高级编程】iOS与OS X多线程和内存管理(八) __block 从栈上复制到堆 截获对象 数组

blk_t blk;
{
     id array = [[NSMutableArray alloc] init];
     blk = [^(id obj){
          [array addObject:obj];
          NSLog(@“array count = %ld”, [array count]];
     } copy];
}
blk([[NSObject alloc] init]);
blk([[NSObject alloc] init]);
blk([[NSObject alloc] init]);

// 结果打印:
array count = 1
array count = 2
array count = 3



struct __block_impl {
    void * isa;
    int Flags;
    int Reserved;
    void *FuncPtr;
};

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 addObject:obj];
     NSLog(@“array count = %ld”,[array count]);
}

static void __main_block_copy_0 (struct __main_block_impl_0 *dst, struct __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_imp1_0 *src)
{     
     _Block_object_dispose(src->array, BLOCK_FIELD_IS_OBJECT);
}

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 
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]);




C语言结构体中不能含有附有 __strong 修饰符的变量。
因为编译器不知道应何时进行C语言结构体的初始化和废弃操作,不能很好的管理内存。

但是Objective—C 的运行时库能偶准确把握Block 从栈复制到堆 以及堆上的Block被废弃的时机。


什么时候栈上的Block 会复制到堆呢?
① 调用Block 的copy 实例方法时;
② 将Block 作为函数返回值返回时;
③ 将Block 赋值给附有 __strong 修饰符id类型的类或者Block 类型成员变量时;
④ 在方法名中含有 usingBlock 的Cocoa 框架方法 或者 Grand Central Dispatch 的API中传递Block时。


如果使用 __weak修饰符会如何:

blk_t blk;
{
     id array = [[NSMutableArray alloc] init];
     id __weak array2 = array;
     blk = [^(id obj){
          [array2 addObject:obj];
          NSLog(@“array count = %ld”, [array2 count]];
     } copy];
}
blk([[NSObject alloc] init]);
blk([[NSObject alloc] init]);
blk([[NSObject alloc] init]);

// 结果打印:
array2 count = 0
array2 count = 0
array2 count = 0 



由于附有 __strong 修饰符的变量array在该变量作用域结束时被释放,废弃。nil被赋值到__weak 修饰的array2中。

若 __weak 和 __block 同时使用:
blk_t blk;
{
     id array = [[NSMutableArray alloc] init];
     __block id __weak array2 = array;
     blk = [^(id obj){
          [array2 addObject:obj];
          NSLog(@“array count = %ld”, [array2 count]];
     } copy];
}
blk([[NSObject alloc] init]);
blk([[NSObject alloc] init]);
blk([[NSObject alloc] init]);

// 结果打印:
array2 count = 0
array2 count = 0
array2 count = 0  



即使附有 __block 说明符,附有__strong 修饰符的变量array 也会在该变量的作用域结束的时候被释放废弃,nil被赋值给附有 __weak 修饰符的变量array2中。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值