我正在阅读"Effective Objective-C 2.0: 52 Specific Ways to Improve Your iOS and OS X Programs"。在“第6项”中,作者说在公共ivar上使用指针是一个坏主意,因为编译后的代码将具有硬编码指针偏移量,并且当新的ivar将被添加到类中时,之前使用的指向某些ivars的指针现在可以指向其他变量。
@interface Foo
{
@public
NSString * string;
NSArray * arr;
}
@end
@implementation
...
@end
int main()
{
@autoreleasepool
{
Foo *f=[Foo new];
f->string; //Is it bad idea?
}
return 0;
}
但是,ivars和属性是不是动态的(在编译时不知道偏移量)?正如Cocoa With Love所说:
“所有ivars在现代运行时都是动态的:由于所有ivars遵循此过程,这意味着现代Objective-C运行时中的所有ivars都是动态的,因为它们的绝对偏移在编译时永远不会被知道。”
如果这是真的,那么为什么在伊塔尔上使用指针坏?请提供尽可能多的低级细节。
答案 0 :(得分:7)
如果这是真的,那么为什么在伊塔尔上使用指针坏?请 提供尽可能多的低级细节。
因为它破坏了封装。
如果Foo
更改时,类string
有一些应该触发的自定义逻辑怎么办?或者它必须进行计算?或Foo
想要将string
存储为唯一的?或者其他什么想要观察所述房产的变化?或者Foo
想要稍后更改存储语义?或者有人想要继承Foo
并改变那里的行为?
答案 1 :(得分:2)
没问题:" 64位Objective-C中的所有实例变量都是非脆弱的。也就是说,当类或超类更改其自己的ivar布局时,使用类的ivars的现有编译代码不会中断。特别是,框架类可以添加新的ivars,而不会破坏针对先前版本的框架编译的子类。" (https://developer.apple.com/LIBRARY/mac/releasenotes/Cocoa/RN-ObjectiveC/index.html)
当然,这也适用于32位现代运行时。
除了实施技术性之外,它还是一个非常糟糕的设计,正如bbum所说。