Is there any reason to declare ivars if you're using properties exclusively in Objective-C?

I tend to use properties exclusively in my classes, especially now that you can declare properties in a class extension thanks to the modern Objective-C 2.0 runtime—I use this feature to create "private" properties.

My question is if there is any good reason to ever declare ivars in a class interface anymore. I prefer my public-facing interfaces to be as minimal and clean as possible, only revealing aspects of my class that are pertinent.

For example, I would tend to do the following:

MyClass.h:

@interface MyClass : NSObject

@property (nonatomic, copy) NSString * publicString;
@property (nonatomic, copy, readonly) NSString * readOnlyString;

@end

MyClass.m:

@interface MyClass ()

@property (nonatomic, copy, readwrite) NSString * readOnlyString;
@property (nonatomic, copy) NSString * privateString;

@end

@implementation MyClass

@synthesize publicString = publicString_;
@synthesize readOnlyString = readOnlyString_;
@synthesize privateString = privateString_;

- (void)init
{
    self = [super init];

    if (self != nil)
    {
        self.publicString = @"Public String";
        self.readOnlyString = @"Read-Only String";
        self.privateString = @"Private String";
    }

    return self;
}

- (void)dealloc
{
    [publicString_ release];
    [readOnlyString_ release];
    [privateString_ release];

    [super dealloc];
}

@end

Code style preferences aside, are there any issues with avoiding ivars entirely like this?


I may have found an answer that's suitable enough for me to explicitly back my properties with ivars. It doesn't appear as if the debugger will list any automatically synthesized ivars, so there's no way to just drill through self during debugging and check various values other than manually calling the property accessors, which is tedious. Unless they change this, this is probably more than enough reason for me to just go back to declaring ivars explicitly.


The main issue, if it bothers you at all, is that per Cocoa With Love, dynamic instance variables such as those you're using aren't supported by runtimes other than those for 64bit Intel/PowerPC (fixed per Chuck's comment below) and ARM (for iOS).

I'm not currently able to find an authoritative Apple document on the issue; note that restricting to the latest OS X, v10.6, is not sufficient since it is available for and supported on the 32bit Intel machines that Apple shipped immediately after switching from PowerPC.

Late extra thought: without knowing about any potential changes in Xcode 4, a good reason to declare otherwise private instance variables within the header file is to mark them as IBOutlets and wire them up graphically. That's really only relevant to a very specific type of class and member variable though, admittedly.


I have to agree with LucasTizma on the debugging issue.

When I began using XCode4, I started not explicitly declaring ivars and let them be created for me using @synthesize aVar = _aVar syntax. While trying to debug code, I noticed that I couldn't hover the cursor over the variable and see its value.

For me, this is just unacceptable. I guess it's back to declaring them explicitly.