gpt4 book ai didi

objective-c - 为什么在if语句中设置Block变量会导致崩溃?

转载 作者:行者123 更新时间:2023-12-03 16:18:05 24 4
gpt4 key购买 nike

我在“Effective Objective-C 2.0”一书中找到了一个示例块

void (^block)();
if (/* some condition */) {
block = ^ {
NSLog(@"Block A");
};
} else {
block = ^ {
NSLog(@"Block B");
};
}
block();

代码很危险,这是本书中的解释:

The two blocks that are defined within the if and else statements are allocated within stack memory. When it allocates stack memory for each block, the compiler is free to overwrite this memory at the end of the scope in which that memory was allocated. So each block is guaranteed to be valid only within its respective if-statement section. The code would compile without error but at runtime may or may not function correctly. If it didn’t decide to produce code that overwrote the chosen block, the code would run without error, but if it did, a crash would certainly occur.



我不理解“如果不决定生成覆盖所选块的代码,则该代码将运行而不会出错,但是如果发生,肯定会导致崩溃。”

有人可以解释并举例吗?

最佳答案

问题类似于在函数本地创建的C数组,然后在函数返回后使用它:

#import <Foundation/Foundation.h>

dispatch_block_t global_block;
int * global_arr;

void set_globals(void)
{
if( YES ){
global_block = ^{
NSLog(@"Summer is butter on your chin and corn mush between every tooth.");
};
int arr[5] = {1, 2, 3, 4, 5};
global_arr = arr;
}
}

void write_on_the_stack(int i)
{
int arr[5] = {64, 128, 256, 512, 1024};
int v = arr[3];

dispatch_block_t b = ^{
int j = i + 10;
j += v;
};

b();
}


int main(int argc, const char * argv[])
{

@autoreleasepool {

set_globals();

write_on_the_stack();

global_block();

NSLog(@"%d", global_arr[0]); // Prints garbage
}
return 0;
}

可以将堆栈上用于存储数组值的空间用于任何目的。我在这里使用单独的功能,因为它最可靠地演示了问题。对于您的确切情况,在 if块和同一函数中进行访问的情况下,编译器仍然可以自由地重用堆栈空间。可能不是,但是您不能依靠它。您正在破坏语言的范围规则(源自C)。

但是,正如Jesse Rusak和CrimsonChris在评论中指出的那样,使用在ARC 下编译的Block型变量 ,该Block像数组一样在堆栈上创建,但是当将其存储在堆栈中时从堆栈中复制(到堆中)。强指针。默认情况下,所有对象指针(包括您的全局指针)都是强的。

如果您不使用ARC进行编译,那将是不可靠的。我不能用当前的编译器提出一个失败的示例,但是同样,它违反了规则,编译器没有义务做您想要的事情。

关于objective-c - 为什么在if语句中设置Block变量会导致崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24292588/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com