32

I'm new to C, new to objective C. For an iPhone subclass, Im declaring variables I want to be visible to all methods in a class into the @interface class definition eg

@interface myclass : UIImageView {
    int aVar;
}

and then I declare it again as

@property int aVar;

And then later I

@synthesize aVar;

Can you help me understand the purpose of three steps? Am I doing something unnecessary?

Thanks.

Nigel
  • 596
  • 1
  • 5
  • 12
  • 1
    The first one is to make Objective-C compatible with C. The second one is declare the property. The third one is so you can associate the property's definition with a specific translation unit. Welcome to C. – Frank Krueger Jan 29 '10 at 03:49

6 Answers6

59

Here, you're declaring an instance variable named aVar:

@interface myclass : UIImageView {
    int aVar;
}

You can now use this variable within your class:

aVar = 42;
NSLog(@"The Answer is %i.", aVar);

However, instance variables are private in Objective-C. What if you need other classes to be able to access and/or change aVar? Since methods are public in Objective-C, the answer is to write an accessor (getter) method that returns aVar and a mutator (setter) method that sets aVar:

// In header (.h) file

- (int)aVar;
- (void)setAVar:(int)newAVar;

// In implementation (.m) file

- (int)aVar {
    return aVar;
}

- (void)setAVar:(int)newAVar {
    if (aVar != newAVar) {
        aVar = newAVar;
    }
}

Now other classes can get and set aVar via:

[myclass aVar];
[myclass setAVar:24];

Writing these accessor and mutator methods can get quite tedious, so in Objective-C 2.0, Apple simplified it for us. We can now write:

// In header (.h) file

@property (nonatomic, assign) int aVar;

// In implementation (.m) file

@synthesize aVar;

...and the accessor/mutator methods will be automatically generated for us.

To sum up:

  • int aVar; declares an instance variable aVar

  • @property (nonatomic, assign) int aVar; declares the accessor and mutator methods for aVar

  • @synthesize aVar; implements the accessor and mutator methods for aVar

Steve Harrison
  • 103,209
  • 15
  • 83
  • 71
12

This declares an instance variable in your object:

@interface myclass : UIImageView {
    int aVar;
}

Instance variables are private implementation details of your class.

If you want other objects to be able to read or set the value of the instance variable (ivar), you can declare it as a property:

@property int aVar;

This means that the compiler expects to see setter and getter accessor methods for the property.

When you use the @synthesize keyword, you are asking the compiler to automatically generate setter and getter accessor methods for you.

So, in this case the compiler will generate code similar to this when it encounters the @synthesize keyword:

- (int) aVar
{
    return aVar;
}

- (void)setAVar:(int)someInt
{
    aVar = someInt;
}

By default on the iPhone (and on the 32-bit runtime on the Mac), @synthesize requires an instance variable to be present in order to store the property's value. This ivar is usually named the same as the property, but doesn't have to be, for instance you could do this:

@interface myclass : UIImageView {
    int aVar;
}

@property int someValue;

@synthesize someValue = aVar;

Neither @synthesize nor @property are actually required, you can create your own getter and setter methods, and as long as you create them using Key-Value Coding-compliant syntax, the property will still be usable.

The requirement for an ivar to be present as well as the @property declaration is due to the fragile base class limitation of the 32-bit Objective-C runtime on both the Mac and iPhone. With the 64-bit runtime on the Mac you don't need an ivar, @synthesize generates one for you.

Note that there are numerous keywords you can use with your @property declaration to control what sort of synthesized accessor code is created, such as readonly for a getter-only accessor, copy, atomic, nonatomic and so on. More information is in the Objective-C 2.0 Programming Language documentation.

Rob Keniger
  • 45,217
  • 6
  • 98
  • 134
  • 1
    Thanks - why do I need setter and getter methods (assuming they are the generic ones created by synthesize)? Are they required in order for a property to be visible to external classes? – Nigel Jan 29 '10 at 03:59
  • @Nigel: Yes—if you don't have setter and getter methods, no other classes will be able to access or change the instance variable (instance variables are private). – Steve Harrison Jan 29 '10 at 04:12
  • Great explanation +1. @Rob Keniger – Chisx Jan 19 '14 at 23:45
1

Classes can have instance variables (ivars). These are in the first section, and are only visible to code in that class, not any outside code. I like to prefix them with an underscore to show their internal-ness. In low level terms, the ivars are added as an additional member to the struct that the class you are creating uses internally.

The second declaration, @property, is a declared property. It is not required (except when you are using @synthesize), but it helps other programmers (and the compiler!) know that you are dealing with a property, and not just two methods -setAVar and -aVar, which is the alternative way of doing this.

Thirdly, the @synthesize actually creates the methods to set and access the property from outside the class. You can replace this with your own setter and getter methods, but only do that if you need to, as the built-in ones have some features that you would otherwise have to code yourself. In fact, using the @synthesize aVar = _someVariable; syntax, you can have your property actually reference a differently named instance variable!

Short version: The @property is just a hint to the compiler and other programmers that you are making a property and not just getter/setter methods. The instance variables are internal to the class, and otherwise cannot be normally accessed from outside it. The @synthesize just creates simple getters and setters for you, to go with your @property, but you can also just code those getters and setters yourself, like any other method.

Grant Paul
  • 5,700
  • 2
  • 30
  • 36
  • Thanks - Is it recommended to use synthesized methods inside the class that owns them? eg should I use [self setaVar:123]; rather than aVar=123? – Nigel Jan 29 '10 at 04:00
  • @Nigel: I think it's generally best to use accessors and mutators within the class. You might find my question http://stackoverflow.com/questions/1551966/properties-and-instance-variables-in-objective-c helpful. – Steve Harrison Jan 29 '10 at 04:30
0
Class A      

      @interface myclass : UIImageView {
    int aVar;
}

If you declare like this then you can only use this variable within your class A.


But suppose in Class B

    A *object=[A new];
object.aVar---->not available



For this you should **declare aVar as a property in Class A**

so class A should look like 

Class A      

  @interface myclass : UIImageView {
    int aVar;
}
@property int iVar;


and 


.m file 
@synthesize iVar;



So now you can use this iVar in another class Suppose B


 Class B
#import "Class A.h"

    enter code here

A *object=[A new];
object.aVar---->available
means
object.aVar=10;
Nagendra Tripathi
  • 903
  • 12
  • 23
0

@interface declares the instances variables of a class in obj-c. You need it to create an instance variable. However the variable is not visible outside the class by default (as the field is by default protected).

@property tells the compiler to specify a particular property accessor (get/set) method. However, you will need to use @synthesize to actually have the compiler generate the simple accessors automatically, otherwise you are expected to create them on your own.

futureelite7
  • 11,227
  • 9
  • 51
  • 85
0

I recently started learning iphone apps. As per my knowledge @property is used in .h file as a setter method and @synthesize in .m file as getter method. In Java we use setter and getter methods, same as Java, in Objective C we use @property and @synthesize.

Please forgive me If u think I mislead you.

  • Not quite. @ property declares attributes that can be got and/or set using dot notation. @ synthesize actually creates the underlying methods in the implementation, and gives you the opportunity to specify the name of the ivar that backs the public method name. With modern versions of Xcode/LLDB the @ synthesize keyword is unneeded as it's automatically created by the compiler. (The spaces between the @ and the property/synthesize as StackOverflow thinks I'm trying to notify people!) – rickerbh Oct 27 '12 at 02:31