10

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?

CIFilter
  • 8,647
  • 4
  • 46
  • 66

4 Answers4

8

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.

CIFilter
  • 8,647
  • 4
  • 46
  • 66
  • I do, but it's a pain in the but to use GDB directly because it doesn't support dot syntax. – CIFilter Aug 26 '11 at 00:06
  • Minus the egregious misspelling of "butt", in addition, the latest version of Xcode seems to offer "helpful" autocomplete suggestions in the debugger console, but it doesn't bother to move the cursor forward, so it just ends up being a terrible mess. Ugh... – CIFilter Sep 02 '11 at 01:22
  • What is the latest version? I'm still on SL. – Denis Mikhaylov Sep 02 '11 at 06:14
  • 1
    If you use lldb instead of gdb then you can see the property values. – featherless Dec 06 '11 at 03:09
3

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.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • 1
    Actually, as correctly noted in that CWL entry, 64-bit PPC is supported as well. It's just 32-bit platforms other than ARM that get the legacy runtime. – Chuck Feb 05 '11 at 01:45
  • Yeah, I recall that the features I'm using are only available on the modern runtime, but I'm iOS-only at this point, so that's not so consequential. – CIFilter Feb 05 '11 at 01:45
  • In that case, it's difficult to come up with reasons in favour of ivar declaration in the @interface. All I can think of — while trying to play devil's advocate — is enabling performance hacks that, when not playing devil's advocate, I'd be completely against anyway. – Tommy Feb 05 '11 at 16:12
  • Oh, actually, I guess that exposing member variables to the scrutiny of Interface Builder is something very useful and a definite reason to put ivars into a header file. I've updated my answer. – Tommy Feb 07 '11 at 16:15
  • I expose properties to Interface Builder, not ivars, and this works just fine. – CIFilter Feb 09 '11 at 22:51
1

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.

edcincy
  • 321
  • 2
  • 3
  • 14
  • This is probably a bug or shortcoming with GDB, which is still the only debugger available for iOS. Hopefully LLDB will be ready for iOS use soon enough and will fix this issue. – CIFilter Apr 06 '11 at 23:15
0

Beyond Tommy's concern, declaring an ivar is certainly good practice, especially if your code might be reused or if you might come back to your code sometime.

FeifanZ
  • 16,250
  • 7
  • 45
  • 84
  • 1
    I don't understand why this is the case. Why is it a good practice? It's just data being managed by my class, but properties have the convenience of memory management and other attributes, so I don't see why using ivars is considered good practice. – CIFilter Feb 05 '11 at 03:18
  • It makes it clear that your class is storing that data. Properties do not necessarily have to correspond to ivars; IMO classes *own* their ivars (ivars are fundamentally a part of the class); properties are just that—properties. It's really a conceptual thing. – FeifanZ Feb 05 '11 at 16:22
  • I guess I can see your point there. My opinion on it is that other classes shouldn't care one way or another whether a class's properties are ivar backed or determined by custom accessors. But I do see your point. – CIFilter Feb 05 '11 at 19:53
  • Generally (especially as you can see with Apple's code) you access another's class's properties, not its ivars. The class can have more (or less) ivars to hold other values that users of the class shouldn't be concerned with. – FeifanZ Feb 07 '11 at 00:10