1

I do not quite understand the way of declaring instance variable and property. Can someone explain in detail the difference of the two codes below? In the second method, if I use _name for instance variable, is it the same function as the way declaring name in first code? Thanks!

First Code:

//  OrderItem.h
#import <Foundation/Foundation.h>

@interface OrderItem : NSObject

{

  @public NSString *name;

}

-(id) initWithItemName: (NSString *) itemName;

@end


//  OrderItem.m
#import "OrderItem.h"

@implementation OrderItem

-(id) initWithItemName: (NSString *) itemName {

     self = [super init];

      if (self) {

          name = itemName;

         NSLog(@"Initializing OrderItem");
   }

     return  self;

   }

@end

Second Code:

//  OrderItem.h
#import <Foundation/Foundation.h>

@interface OrderItem : NSObject

 @property (strong,nonatomic) NSString *name;

-(id) initWithItemName: (NSString *) itemName;

@end


//  OrderItem.m
#import "OrderItem.h"

@implementation OrderItem

-(id) initWithItemName: (NSString *) itemName {

     self = [super init];

      if (self) {

          _name = itemName;

         NSLog(@"Initializing OrderItem");
   }

     return  self;

   }

@end
Mike
  • 817
  • 1
  • 8
  • 15
  • Not an exact duplicate (though I think there is one; need to find it), but see http://stackoverflow.com/questions/12899305/property-is-backed-by-an-ivar-what-technically-does-that-mean/12899768#12899768 – Rob Napier Aug 07 '16 at 13:26
  • Mike there is lot of answer for your question in Stackoverflow.Even I can give answer now but everywhere you can see the solution according to your question. – user3182143 Aug 07 '16 at 13:50

2 Answers2

1

In the first case you have declared an instance variable (usually called an ivar in Objective-C).

In the second case you have declared a property. A property is a set of two methods, a getter and a setter, usually accessed using dot notation, e.g. self.name. However, an ivar is automatically synthesized for the property with the name _name. That instance variable is what you are accessing in your init.

You can actually change the name of the ivar using @synthesize name = _myName or not have it at all (if you declare the getter and setter manually, no ivar will be synthesized).

Objective-C properties are a rather complicated topic so don't worry if you don't understand it immediately.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • Hi Sulthan, thank you very much! In practice, I prefer the second way, so if I code in the second way, there should be no problem, right? – Mike Aug 07 '16 at 13:44
  • 1
    @Mike Properties are generally preferred over instance variables. – Sulthan Aug 07 '16 at 13:50
  • @Sulthan Hi Sulthan, got it. I have accepted your answer. Have a nice Sunday! – Mike Aug 07 '16 at 13:55
1

Properties are public which means that other classes can read and write them (even classes that aren't subclasses of the class that declares the property). In addition to that, properties provide a getter and a setter method (mutator methods). The getter of a property gets called every time you access the property

NSString *aName = self.name;

Whereas the setter is accessed every time you write or assign to a property.

self.name = @"Some name";

Instance variables (or ivars) are, by default, only visible for the class that declares it and its subclasses (also known as being encapsulated by their class). You can change this default behavior when you add the keyword @public to your ivar declaration though.

Marcel Voss
  • 360
  • 2
  • 9
  • @user3182143 Thanks! I hope my answer helped you a bit. – Marcel Voss Aug 07 '16 at 13:47
  • Hi Marcel, thanks a lot! According to the function of the code, in practice both ways have no problem, right? – Mike Aug 07 '16 at 13:48
  • Well, ivars are public too. Or better said, there is no concept of public or private in Objective-C. If you declare your ivars in the header, they are accessible externally, too. There are only accessed using the `->` notation. – Sulthan Aug 07 '16 at 13:51
  • @Mike Yes, you can use both ways. Although, I would recommend to use properties only if it's necessary since they are public to other classes as long as they are declared in your header. You shouldn't disclose too much information to other classes without having to. – Marcel Voss Aug 07 '16 at 13:53
  • @MarcelVoss There is absolutely zero difference between ivars and properties when speaking about accessibility. – Sulthan Aug 07 '16 at 13:56
  • @MarcelVoss Thank you for your help, too. Have a great Sunday! – Mike Aug 07 '16 at 13:56
  • @Sulthan As I said, by **default** they are only visible to its classes. – Marcel Voss Aug 07 '16 at 13:56
  • @Sulthan There _is_ a difference. Even if you declare your ivars in your header, you can't access them from a different class that isn't a subclass of the class that declares your ivars – this is even one of the fundamental principal of OOP. By default, ivars are protected and unless you declare your ivar in a header, it is even difficult to determine it exists. – Marcel Voss Aug 07 '16 at 14:03
  • @Sulthan The non-default for an ivar would be to declare it as `@public`. Then it would be also accessible from other classes using the arrow operator (->) which points to the ivar. – Marcel Voss Aug 07 '16 at 14:10