Santiago V.
Santiago V.

Reputation: 1118

Objective-C properties, how do they work?


Assume we have a class Foo with a property bar.
Declared like this in the header:

@interface Foo : NSObject {
    int bar;
}

@property (nonatomic, assign) int bar;

@end

In the .m I have @synthesize bar; of course.

Now, my question is, if I remove the int bar; line, the property behaves the same way, so, is that line really necessary? Am I missing some fundamental concept?

Thanks!

Upvotes: 2

Views: 732

Answers (5)

Steven Fisher
Steven Fisher

Reputation: 44856

The "modern" Objective-C runtime generates ivars automatically if they don't already exist when it encounters@synthesize.

Advantages to skipping them:

  • Less duplication in your code. And the @property gives the type, name and use (a property!) of the ivar, so you're not losing anything.
  • Even without explicitly declaring the ivar, you can still access the ivar directly. (One old release of Xcode has a bug that prevents this, but you won't be using that version.)

There are a few caveats:

  • This is not supported with the "old" runtime, on 32-bit Mac OS X. (It is supported by recent versions of the iOS simulator.)
  • Xcode may not show autogenerated ivars in the debugger. (I believe this is a bug.)

Because of the debugger issue, at the moment I explicitly add all my ivars and flag them like this:

@interface Foo : NSObject {
    #ifndef SYNTHESIZED_IVARS
    int ivar;
    #endif
}

@property (nonatomic, assign) int bar;

@end

My plan is to remove that block when I've confirmed the debugger is able to show the ivars. (For all I know, this has already happened.)

Upvotes: 3

Phil Willoughby
Phil Willoughby

Reputation: 1734

If there is not a instance variable (ivar) with the same name as the property the modern runtime creates a new ivar of the specified property name to hold the property value when it sees @synthesize.

If your property was not defined nonatomic and you want your code to be threadsafe it may help you to not reference the ivar (whether you declared it or it was synthesized), as that will prevent you from accessing it directly when the property is being changed. To my knowledge there is no way to acquire the same lock that is acquired by @synthesize for an atomic property and therefore you cannot perform safe reads of an atomic property's ivar other than by its synthesized accessor (unless you code an explicit setter and lock something yourself). If you are interested in writing you own accessors I have a blog post on that here.

I believe it is more usual to have an explicit ivar for each property, but this may be because most code is intended to be compatible with the legacy runtime rather than because it is inherently good practice.

Edit: I have corrected paragraph 1 to say that the synthesized ivar has the name of the property; I couldn't see any discussion of its name in Apple's docs so I had assumed it was not user accessible. Thanks to the commenters for pointing this out.

Upvotes: 3

Peter
Peter

Reputation: 8575

In the latest Objective-C runtime, it turns out that all ivars (in this case, bar) are dynamically added to the class from the @property/@synthesize declaration and do not need a corresponding ivar declaration in the class header. The only caveat to this is that latest Objective-C runtime which supports this feature does not include support for 32 bit applications.

This page from the excellent Cocoa with Love blog explains more.

Upvotes: 2

Ole Begemann
Ole Begemann

Reputation: 135540

If you are using the modern Obj-C runtime (e.g. with the LLVM compiler in Xcode 4), the compiler can automatically create the instance variable for you. In that case, you don't need to declare the ivar.

The modern runtime is supported by iOS, the iOS Simulator and 64-bit Mac OS X. You can't build your project for 32-bit OS X with the modern runtime.

Upvotes: 1

Goibniu
Goibniu

Reputation: 2221

I believe it only works that way in 64bit mode. If you try to build for a 32bit target, it will throw an exception.

Scott Stevenson has a good overview of the objective-c 2 changes, and mentions the 64bit runtime changes here

Upvotes: 0

Related Questions