objective-cpropertiesivar

Why is a pointer on an ivar bad in Objective-C?


I am reading "Effective Objective-C 2.0: 52 Specific Ways to Improve Your iOS and OS X Programs". In "Item 6", the author says that using a pointer on a public ivar is a bad idea, because compiled code will have hardcoded pointer offset, and when new ivar will be added to class, then previously used pointers to some ivars can now point on other variable.

@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;
}

But, aren't ivars and properties dynamic (offset is not known at compile-time)? As Cocoa With Love says:

"All ivars are dynamic in the modern runtime: Since this procedure is followed for all ivars, that means that all ivars in the modern Objective-C runtime are dynamic in that their absolute offsets are never known at compile-time."

If that's true, then why is using a pointer on an ivar bad? Please provide as much low-level detail as possible.


Solution

  • If that's true, then why is using a pointer on an ivar bad? Please provide as much low-level detail as possible.

    Because it breaks encapsulation.

    What if class Foo has some custom logic that should be fired when string changes? Or it has to do a calculation? Or Foo wants to make the storage of string unique-ified? Or something else wants to observe changes to said property? Or Foo wants to change the storage semantics later? Or someone wants to subclass Foo and change the behavior there?