153

I have seen the following piece of code:

//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;

//example.m
@synthesize mapView = mapView1

What is the relation between mapView and mapView1? Does it create a set and get method for mapView1?

Seanny123
  • 8,776
  • 13
  • 68
  • 124
Hoang Duy Nam
  • 1,531
  • 2
  • 10
  • 3
  • 1
    Update: but with the latest tool set @synthesize is now (almost) never needed. See answer to [Other Stack Overflow Question](http://stackoverflow.com/questions/17019798/about-naming-the-instance-variable-in-objective-c/17019883#17019883). – Ali Beadle Jun 10 '13 at 16:11

8 Answers8

231

In your example, mapView1 is an instance variable (ivar), a piece of memory storage that belongs to an instance of the class defined in example.h and example.m. mapView is the name of a property. Properties are attributes of an object that can be read or set using the dot notation: myObject.mapView. A property doesn't have to be based on an ivar, but most properties are. The @propertydeclaration simply tells the world that there is a property called mapView.

@synthesize mapView = mapView1;

This line tells the compiler to create a setter and getter for mapView, and that they should use the ivar called mapView1. Without the = mapView1 part, the compiler would assume that the property and ivar have the same name. (In this case, that would produce a compiler error, since there is no ivar called mapView.)

The result of this @synthesize statement is similar to if you had added this code yourself:

-(MKMapView *)mapView
{
   return mapView1;
}

-(void)setMapView:(MKMapView *)newMapView
{
  if (newMapView != mapView1)
  {
    [mapView1 release];
    mapView1 = [newMapView retain];
  }
}

If you do add that code to the class yourself, you can replace the @synthesize statement with

@dynamic mapView;

The main thing is to have a very clear conceptual distinction between ivars and properties. They are really two very different concepts.

Felixyz
  • 19,053
  • 14
  • 65
  • 60
31

@synthesize creates a getter and a setter for the variable.

This lets you specify some attributes for your variables and when you @synthesize that property to the variable you generate the getter and setter for the variable.

The property name can be the same as the variable name. Sometimes people want it to be different so as to use it in init or dealloc or when the parameter is passed with the same variable's name.

Reuben Mallaby
  • 5,740
  • 4
  • 47
  • 45
vodkhang
  • 18,639
  • 11
  • 76
  • 110
17

From the documentation:

You use the @synthesize keyword to tell the compiler that it should synthesize the setter and/or getter methods for the property if you do not supply them within the @implementation block.

Koen.
  • 25,449
  • 7
  • 83
  • 78
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
9

As I just run into this problem when editing legacy code I want to make additional notes to the existing answers one needs to be aware of.

Even with a newer compiler version it sometimes does make a difference if you omit @synthesize propertyName or not.

In the case you declare an instance variable without underscore while still synthesizing it, such as:

Header:

@interface SomeClass : NSObject {
   int someInt;
}
@property int someInt;
@end

Implementation:

@implementation SomeClass
@synthesize someInt;
@end

self.someInt will access the same variable as someInt. Not using a leading underscore for ivars does not follow the naming conventions but I just came into a situation where I had to read and modify such code.

But if you now think "Hey, @synthesize is not important any more as we use a newer compiler" you are wrong! Your class then will result in having two ivars, namely someInt plus an autogenerated _someInt variable. Thus self.someInt and someInt will not address the same variables any more. If you don't expect such behavior as I did this might get you some headache to find out.

Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127
  • "synchronize" != "synthesize"? – jameshfisher May 08 '15 at 15:49
  • Yes, these are 2 different concepts. `@synchronize` is a directive for how to synchronize threads when accessing the property and `@synthesize` is for binding the property to an instance variable through getters and setters. – Lars Blumberg May 08 '15 at 21:08
  • 1
    jameshfisher's comment was meant to alert you that you have confused synchronize and synthesize in your answer. You use the two interchangeably. – Maple May 10 '16 at 17:32
  • 1
    Thanks for making me aware of that! I totally oversaw that, I've updated the answer to not use the non-existing @synchronize keyword. – Lars Blumberg May 11 '16 at 08:36
  • 1
    In that case, xcode 10 will warn about the issue: `Autosynthesized property 'someInt' will use synthesized instance variable '_someInt', not existing instance variable 'someInt'`. (I don't know in which version of xcode this warning was added.) – zwcloud Oct 09 '18 at 02:56
7

As per apple documentation @Synthesize is used only to rename instance variables. For example

@property NSString *str;

@synthesize str = str2; 

Now in the class you can not use _str as the above line has renames the instance variable to str2

@property allows objects to be used by objects in other classes, or in other words makes the object public.

PT Vyas
  • 722
  • 9
  • 31
  • 3
    Apparently, starting with Xcode 4.4, Clang provides support for autosynthesis of declared properties. So @synthesize is no longer necessary for most cases. See http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html – huyz May 22 '14 at 17:53
5

When you create a property in @interface, that property will be automatically back by an instance variable named as _propertyName. So when you create a property named as firstName, behind the scene compiler will create an instance variable named as _firstName by default. Compiler will also create the getter and setter method for you(i.e. firstName, setFirstName).

Now when you synthesize the property by @synthesize firstName, you are simply telling the compiler rename my instance variable(_firstName) by firstName. If you want to rename your backed up instance variable by different name you can simply assign different name while synthesizing the property name(i.e. @synthesize firstName = myFirstName), by doing this your property is backed up by an instance variable named as myFirstname.

So, in short, most of the time @synthesize used to rename your instance variable backed up by your property.

Mahadev Mandale
  • 449
  • 5
  • 16
2

See the apple docs

Basically the synthesize creates a setMapView and mapView methods which set and get mapView1

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
2

It creates getter and setter for your object. You can access with something like this :

MKMapView* m = object.mapView;

or

object.mapView = someMapViewObject

mapView1 is the name of the ivar in the class, mapView is the name for the getter / setter method(s).

Sebastian Sastre
  • 2,034
  • 20
  • 21
Nyx0uf
  • 4,609
  • 1
  • 25
  • 26