Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

objective-C property also defined as an instance variable

I have defined

@interface FooObject : NSObject
@property (nonatomic, readonly) Foo *foo;
@end

Then in the implementation:

@implementation FooObject {
Foo *_foo;
...
}

But, my understanding is that creating the property

@property (nonatomic, readonly) Foo *foo;

in the interface, also creates

_foo

So my question is, is there anything gained by doing this, what are the possible advantages.

like image 450
iOScoder Avatar asked Jul 25 '26 03:07

iOScoder


1 Answers

You ask:

is there anything gained by doing this?

No, there is no advantage in manually declaring the instance variable. In fact, there are disadvantages in doing so because you'll be susceptible to mistyping the ivar name (or incorrectly using @synthesize statement), ending up with two ivars, the one that you manually created and the one that was synthesized for you. It just introduces the possibility of possible typographical errors leading to hard to diagnose bugs.

A couple of caveats:

  1. This pattern of manually defining ivars to back your properties is a bit of an anachronism, dating back before the Objective-C compiler could synthesize these ivars for you.

    It's worth noting that if you're using an old Objective-C compiler (e.g. especially for those experimenting with Objective-C on non-macOS platforms or using old versions of Xcode), the compiler might not be able to automatically synthesize these ivars for you, and you'll have to manually do so. Even then, though, you'd use the @synthesize directive to let the compiler do this for you, rather than manually declaring the ivar. Only if you were using an extremely old compiler that predated the introduction of the @synthesize directive would you need to declare the ivar manually.

  2. If you implement all of the accessor methods yourself (i.e. just the getter for read-only properties or both the getter and setter for read-write properties), the compiler will not synthesize the ivar for you. The thinking is, presumably, that if you're writing your own accessor methods, you might have those doing something other than interacting with the customary ivar, so it won't synthesize the ivar for you.

    In this scenario, you'll have to manually synthesize the ivar yourself, if you want one. For example, consider this class:

    @interface Foo: NSObject
    @property (nonatomic) NSInteger bar;
    @end
    

    If you implement both accessors:

    - (void)setBar:(NSInteger)bar {
        // do something, and then update ivar
        _bar = bar;
    }
    
    - (NSInteger)bar {
        // do something, and then retrieve ivar
        return _bar;
    }
    

    Then you'll have to manually synthesize the ivar yourself inside the @implementation:

    @synthesize bar = _bar;
    

    Note, I didn't manually define a _bar ivar, but I rather still let the compiler do so, but I had to manually initiate that with the @synthesize directive.

    My above example is with a read-write property. The same issue applies with read-only properties for which you've implemented your own custom getter.

    Obviously, if you didn't implement custom accessor methods (and we generally don't), you would not have to manually synthesize the ivar. Just define the @property, and you're done.

like image 90
Rob Avatar answered Jul 28 '26 04:07

Rob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!