搜索

首页  >  问答  >  正文

objective-c - NSStackBlock 的内存的一个疑问

很常见的这个关于block 的题

void exampleB_addBlockToArray(NSMutableArray *array) {
    char b = 'B';
    [array addObject:^{
        printf("%cn", b);
    }];
}

void exampleB() {
    NSMutableArray *array = [NSMutableArray array];
    exampleB_addBlockToArray(array);
    void (^block)() = [array objectAtIndex:0];
    block();
}

Without ARC, the block is an NSStackBlock allocated on the stack of exampleB_addBlockToArray(...). By the time it executes in exampleB(), the the block is no longer valid, because that stack has been cleared.

解释只说明了原理。我有一个理解不知道对不对?
NSStackBlock 类似于一个栈“对象”,不像堆上的局部对象变量 在return 返回它,后所指的内容依然不会被释放。所以在函数结束后其实array 所存的对象(point)依然存在,只是所指的内存(内容)被释放掉了?

伊谢尔伦伊谢尔伦2844 天前577

全部回复(1)我来回复

  • 滿天的星座

    滿天的星座2017-05-02 09:21:15

    尝试答一下,因为我对非 ARC 的情况不太有把握,不过我的理解跟你是一样的~

    按照它的解释,非 ARC 的 block 是放在栈上而不是堆上的,那就是跟基础类型一样。在exampleB_addBlockToArray里那个 block 的定义就是int b = 1;这样,保存在数组里的是指向 b 的指针,也就是它的地址&b,也就是一个0x1234567……这样的东西。

    但是 b 是exampleB_addBlockToArray这个函数的局部变量。所以在这个函数结束的时候,它用的那块儿内存就被『释放』掉了,实际上是标记为『数据已废弃,这块内存可以作为它用』了。

    等到执行的时候,数组里存的那个指针0x1234567……还在,但是它指的那块内存早就不归这个指针管了。有可能是已经写上了别的数据,也有可能还残留着刚才的数据。

    回复
    0
  • 取消回复