When would you NOT want to use @synthesized instance variables?

868 Views Asked by At

In the Modern Objective-C runtime, you can do something like this:

@interface MyClass : NSObject {
}
@property NSString *stringProperty;
@end

@implementation MyClass
@synthesize stringProperty;
@end

It is my understanding with the modern runtime this will not only synthesize the accessors for my property, but also the instance variable itself, so I could then say in one of this class's methods [stringProperty length]; and it would work just as if I'd declared an instance variable.

I've started using this in all my code now, because, well it's one less thing I have to write over and over again. And I've heard with the clang 2.0 compiler, I'll even be able to skip the @synthesize (but that's another matter). But I've been wondering, what are some of the downsides to doing this? When might I truly need an instance variable in addition to my properties?

I know there are sometimes when I want to keep a variable private and not give access to it externally (but then I usually just declare the property in my private class extension, or I don't create a property for it at all, if I don't need accessors for it).

Are there any times when I wouldn't want to do this?

5

There are 5 best solutions below

2
On BEST ANSWER

One possible reason why it might be advisable to not use synthesized instance variables is they are a bit more of a pain to debug in the current version of Xcode (3.2.5). They don't seem to show up in the live debugger view when running code through GDB, the only way to get at them is through the gdb console like po [0xOBJ_ADDRESS propertyName]. Not exactly as nice as a standard, non-synthesized ivar.

Maybe Xcode 4 fixes this but I don't have enough experience with it to say (and it's still under NDA).

More info on this SO question: Seeing the value of a synthesized property in the Xcode debugger when there is no backing variable

3
On

One other reason is to avoid shortcuts to direct variable access.

I try to follow the personal coding convention: - object variable: prefix with underscore '_xxx' - property: named without underscore 'xxx'

This ensure that I never write unintentionally something like

xxx = value;

or

[xxx someMessage];

I want to always use the getter/setter.

self.xxx = value;
[self.xxx someMessage];

This is particularly useful when you are using lazy init for object variables...

2
On

You may want to provide many properties for a single instance variable, e.g., :

  • for accessing an angle value both in degrees and radians
  • for accessing coordinates both in rectangular and in polar systems

In these cases, you don't want to synthesize instance variables (it already exist) nor accessor methods (you want to provide them for doing conversions).

5
On

But I've been wondering, what are some of the downsides to doing this? When might I truly need an instance variable in addition to my properties?

Possible reasons:

  • it allows you to change the instance variable in init and dealloc without tripping over subclass overrides or KVO.
  • the app will compile and run in 32 bit mode on Mac OS X. There are still some Intel Macs out there that don't support 64 bit.

I'm not sure how valid the first point really is. There may be other ways around the issues. The second point is game over though if you need to support older Macs.

2
On

Anytime you need to make a conversion (unless someone knows a better way) in a class you need to serialize. For example if you have a class that has a numeric value. You cannot serialize an integer so you store it as a NSNumber in the class but the property is a integer type.

Another example is if you code as Apple recommends when working with CoreData. They say you should create a custom class derived from NSManagedObject as the Class for your managed object and use a property for each attribute. Then you would use @dynamic instead of @synthesize and no iVar is needed at all.