我们可以假设编译器永远不会重新排序属性赋值吗?请考虑以下事项:
@interface ObjA
@property int x;
@property int y; // When YES, x guaranteed to be set to 10.
@end
ObjA a;
ObjB b;
[a addObserver:b forKeyPath:@"y" options:nil context:&context]
a.x = 10;
a.y = YES;
x是否总是在y之前分配,或者我们是否需要插入内存屏障?
我知道编译器应该检查依赖关系,以确保在a.x之前分配a.y是安全的,但是为了做到这一点,它必须查看所有观察者的所有实现。如果ObjA是图书馆的一部分,那么在链接时间之前它甚至不能知道这些信息,这可能为时已晚,无法进行重新排序?那么可以安全地假设编译器永远不会重新排序属性赋值吗? ivars当然是另一个故事。
答案 0 :(得分:2)
编译器无法重新排序属性分配,因为它无法知道代码的行为在运行时将保持不变。
a.x = 10
与[a setX: 10]
完全相同,因此会进行动态调度。因为它是动态的,所以在编译时无法知道所述调用的潜在副作用。
涉及动态调度的时刻是编译器无法重新执行命令的时刻。