15

If I have a @property which I didn't want to have backed via an ivar I simply omitted the @synthesize and had manual getters which returned a calculated value.

However, now since Xcode 4.4 if I don't specify @synthesize do compiler will automatically generate it. Does that mean it will also generate an ivar even do I don't need/use it?

I could eventually force to not auto-synthesize by using dynamic. However that would be wrong, since @dynamic is supposed to be used for turning off warnings if getter and setter are implemented somewhere else or during runtime.

Community
  • 1
  • 1
znq
  • 44,613
  • 41
  • 116
  • 144
  • Is it a read-only property? If not, it will probably generate a setter and an ivar for it. – Thilo Oct 17 '12 at 11:59
  • 2
    @Thilo read-only properties still have iVars, no question. The whole point of `@synthesize` is to **create the iVars** for you. – Richard J. Ross III Oct 17 '12 at 12:05
  • I do have a setter. However, I don't want an additional ivar to be created. – znq Oct 17 '12 at 12:06
  • Even with a custom getter and no setter? – Thilo Oct 17 '12 at 12:06
  • Yeah, a property without a ivar wouldn't make sense – JonasG Oct 17 '12 at 12:07
  • 1
    If you don't have an ivar, where are you supposed to store the backing value of the property? –  Oct 17 '12 at 12:07
  • 2
    "where are you supposed to store the backing value of the property": manual getters which returned a calculated value – Thilo Oct 17 '12 at 12:08
  • 2
    If you provide all the getters (and setters for readwrite), then no ivar will be generated automatically. If one method is missing, it has to - otherwise it couldn't create that method. – Eiko Oct 17 '12 at 12:09

3 Answers3

37

In my working with this, I've noticed the following behavior.

  1. If you have a readwrite property, don't have a @synthesize, have a getter and don't have a setter, then it will generate the iVar.
  2. If you have a readwrite property, don't have a @synthesize, don't have a getter, and have a setter, then it will generate the iVar.
  3. If you have a readwrite property, don't have a @synthesize and have both a getter and a setter, then it will not generate the iVar.
  4. If you have a readonly property, don't have a @synthesize and don't have a getter, then it will generate the iVar.
  5. If you have a readonly property, don't have a @synthesize and have a getter, then it will not generate the iVar.

From this, I think the general rule is that if you don't have a @synthesize, and have all the methods needed to fully implement the property, then it's assumed to be dynamic and doesn't generate the iVar.

At any rate, if you want to ensure that an iVar is not generated then declare it as @dynamic.


Clarification on @dynamic

From Declared Properties in The Objective-C Programming Language:

You use the @dynamic keyword to tell the compiler that you will fulfill the API contract implied by a property either by providing method implementations directly or at runtime using other mechanisms such as dynamic loading of code or dynamic method resolution.

To me this reads like it OK to mark a property as @dynamic even when you are directly implementing the getter and setter.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • According to various comments here http://stackoverflow.com/questions/1160498/synthesize-vs-dynamic-what-are-the-differences/1160526#1160526 the use of @dynamic is wrong for that, since I'm providing getters and setters. – znq Oct 17 '12 at 12:11
  • Well, this seems correct! It is great to hear it is as simple as that! – hfossli May 30 '14 at 11:02
  • A property is not automatically synthesized if you implement all required accessor methods (getter for a read-only property, getter + setter for a read-write property). -- http://stackoverflow.com/a/16772676/456536 – Míng Apr 22 '16 at 08:10
  • @iwill Yes, I came to the same conclusion: _if you don't have a @ synthesize, and have all the methods needed to fully implement the property, then it's assumed to be dynamic and doesn't generate the iVar_. There was no documentation from Apple, llvm, or clang stating this fact. So, I showed my work. The answer you linked to doesn't provide a source, but asserts it as fact with no explanation. That is not my style. – Jeffery Thomas Apr 22 '16 at 10:04
  • @JefferyThomas Good job, keep your style. But I think this would be a better answer -- "if you don't have a @ synthesize, and have all the methods needed to fully implement the property, then it's assumed to be dynamic and doesn't generate the iVar. There was no documentation from Apple, llvm, or clang stating this fact.". – Míng Apr 22 '16 at 10:55
2

If you mark the property as readonly and implement the getter yourself, it seems that iVar will not be created.

Interface declaration:

@property (nonatomic, readonly) BOOL myBoolProp;

Impementation:

- (BOOL)myBoolProp {
    return true;
}

Trying this:

- (void)viewDidLoad {
    [super viewDidLoad];
    _myBoolProp = true;
}

will generate an error: Use of undeclared identifier '_myBoolProp'

Removing the custom getter method also removes the error, appearing to demonstrate that the iVar has now been generated.

Ian L
  • 5,553
  • 1
  • 22
  • 37
  • 1
    Just because you cannot reference the iVar with the name you expect, doesn't mean it isn't there. I would strongly urge using the runtime to ensure that no iVar is actually generated. – Richard J. Ross III Oct 17 '12 at 12:12
  • 3
    In the WWDC 2012 presentation "Modern Objective C" it's stated that for readonly properties "If you let us synthesize the getter you're going to get an instance variable, otherwise you won't" – Ian L Oct 17 '12 at 12:27
-1

Yes - iVars are still generated by clang (not Xcode, as it is the IDE, clang is the complier that really matters).

If you really don't want iVars, and don't want an implementation, there is the somewhat archaic @dynamic keyword that will do what you want, or you can specify the property in a protocol, which doesn't make it auto-synthesized:

// .h
@property (nonatomic, retain) NSObject *someProp;

//.m
@dynamic someProp; // no iVars generated

// other solution
@protocol MyObjectProtcol<NSObject>

@property (nonatomic, retain) NSObject *someProp;

@end

// now, when you implement the MyObjectProtocol protocol, the property won't auto-synthesize.
Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • So, @Jeffery's observation is incorrect? (If you have a readonly property, don't have a synthesize and have a getter, then it won't generate the iVar.) – Thilo Oct 17 '12 at 12:09
  • @Thilo This was not referring to fringe-cases like what Jeffery was saying. This was referring to the single situation outlined in the OP. So, in most cases, what he was saying is correct. – Richard J. Ross III Oct 17 '12 at 12:11
  • 1
    According to various comments here http://stackoverflow.com/questions/1160498/synthesize-vs-dynamic-what-are-the-differences/1160526#1160526 the use of @dynamic is wrong for that, since I'm providing getters and setters. – znq Oct 17 '12 at 12:14
  • 1
    @znq it is not 'wrong'. The original use case was for that, yes, but the language has evolved, and `@dynamic` becomes much more entertaining, if you do not want iVars flying everywhere. – Richard J. Ross III Oct 17 '12 at 12:19