为什么Objective-C上的指针在ivar上不好?

时间:2014-08-25 20:00:00

标签: objective-c properties ivar

我正在阅读"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都是动态的,因为它们的绝对偏移在编译时永远不会被知道。”

如果这是真的,那么为什么在伊塔尔上使用指针坏?请提供尽可能多的低级细节。

2 个答案:

答案 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所说。