0

Possible Duplicate:
Property Declaration and Automatic Backing Storage Allocation

I'm really confused about this thing.

Is there difference between

@interface MyClass : NSObject {

}
@property(nonatomic, retain) Foo* foo;
@end

and

@interface MyClass : NSObject {
Foo* foo;
}
@property(nonatomic, retain) Foo* foo;
@end

?

I would love get an low level explanation. Thank you!

Community
  • 1
  • 1
user500
  • 4,519
  • 6
  • 43
  • 56

2 Answers2

3

The difference between those two is that the second includes an ivar named foo in your class, while the first doesn't.

If your implementation includes @synthesize foo; and you are using a sufficiently modern compiler, for the first case the compiler will automatically add an appropriate ivar to the class for you. You can even access this implicit ivar later on in the same implementation file as if it were declared as in the second case.

This ivar synthesis is made possible by another feature of modern Objective-C: the fix of the fragile base class problem. In most compiled languages, an ivar is accessed as "object address + ivar offset"; the subclass's ivars necessarily come after the ivars for the base class, so the subclass must know the size of the base class in order to know where its own ivars start. Changing the size of base class (e.g. by adding or removing ivars) therefore requires recompiling all subclasses. Objective-C solves this by storing the size of the class's ivar area in the class metadata and loading it at runtime, and ivar accesses are along the lines of "object address + base class size + ivar offset".

The very-low-level details of how ivar synthesis works are up to the compiler, but it boils down to the compiler arranging for the class's ivar area to be sufficiently large to include space for the synthesized ivars.

Anomie
  • 92,546
  • 13
  • 126
  • 145
2

A short and simple answer: The compiler will auto-generate backing stores for your synthesized properties if you do not explicitly define the ivars to back your properties.

With this you can only access the value using the property (usually a good thing):

@interface MyClass : NSObject {
}
@property(nonatomic, retain) Foo* foo;
@end

self.foo = aFoo; // works
foo = aFoo;      // Nope
self->foo;       // Nope

With this you can access the value both with the property, and directly with the ivar (usually a bad thing to go directly to the ivar);

@interface MyClass : NSObject {
    Foo* foo;
}
@property(nonatomic, retain) Foo* foo;
@end

self.foo = aFoo; // works
foo = aFoo;      // yup
self->foo;       // yes
PeyloW
  • 36,742
  • 12
  • 80
  • 99