Why should I write @synthesize when I provide getter and setter?

Thus, the automatic synthesis of properties is amazing. However, when you provide both getter and setter, you get an error message.

@property (strong, nonatomic) NSArray *testArray; - (NSArray *)testArray { return _testArray; } - (void)setTestArray:(NSArray *)testArray { _testArray = testArray; } 

Error: Use of undeclared identifier '_testArray' .

Adding @synthesize testArray = _testArray; solves the problem. I'm just wondering why this is?

+8
properties objective-c synthesize
source share
3 answers

When you provide both getter and setter, often there is no need for an instance variable, i.e. when you simply forward these messages or save data in other places.

Once one of them is missing, ivar is needed to synthesize this functionality.

If I remember correctly, the analog assumption is also satisfied for readonly properties.

+8
source share

In the last compiler / runtime when you use

 @synthesize testArray = _testArray; 

the compiler creates

  • a _testArray ivar, if it does not already exist;
  • a testArray , if you did not implement it,
  • a setTestArray: if you did not implement it.

If you use

 @synthesize testArray; 

the compiler creates testArray ivar, if it does not already exist, instead of _testArray .

If you are not using @synthesize and rely on autosynthesis, _testArray ivar is only created if (both should apply)

  • _testArray does not exist yet;
  • at least one method has been synthesized (getter for readonly , getter and / or setter for readwrite ).

In your example, you implemented all the methods, so autosynthesis does not synthesize, so it does not create ivar. You can either declare _testArray ivar yourself, or use explicit synthesis like you do.

+8
source share

I did some testing:

In a recent Objective-c convention, you don't need to synthesize properties.

If you do

 @property (strong, nonatomic) Business* theBiz; 

iOs will automatically create a private ivar variable named _theBiz;

If you only implement a getter or setter, it seems to work fine:

 -(void)setTheBiz:(Business *)theBiz { _theBiz = theBiz; } 

However, if you declare BOTH, even if one of them is an empty function, you will get a compilation error.

 -(void)setTheBiz:(Business *)theBiz { _theBiz = theBiz; } -(Business *) theBiz { } 

When you implement the BOTH getter and setter, you get a compilation error saying that therre is not such a thing as _theBiz.

This can be easily fixed by adding:

 @synthesize theBiz = _theBiz; 

But it strikes the whole point of this amazing new Objective-c feature.

I wonder if this is by design, or I just missed something. What does an apple do?

My best guess is a mistake.

Guillaume's answer does not affect this fact.

He said that

at least one method was synthesized

It seems that _theBiz would be created if only ONE from getter or setter is installed. When both are installed, it is no longer created, and this should be a mistake. In fact, none of them should be installed at all, and Ivar will still be created.

The only way to fix this is to explicitly do

 @synthesize theBiz = _theBiz; 
-one
source share

All Articles