6

Specific performance and behaviour difference using properties or accessing the ivars directly.

For Global variables, What is the difference between using this:

@interface myClass (){

    UIImageView *myView;
}

-(void)loadView{

  [super loadView];
  myView = [[UIImageView alloc] initWithFrame:CGrectMake(0,0,100,100)];
}

And doing this:

    @interface myClass (){

    }

    @property (nonatomic, strong) UIImageView *myView; 

@synthesize myView = _myView;

    -(void)loadView{

    [super loadView];
    myView = [[UIImageView alloc] initWithFrame:CGrectMake(0,0,100,100)];
    }

What benefits can we have with every approach? What are the reasons to recommend to always uses properties?

Antonio MG
  • 20,382
  • 3
  • 43
  • 62
  • Here's an [answer to a similar question](http://stackoverflow.com/a/5031363/1245406). – Squatch Mar 15 '12 at 15:04
  • 1
    Your second example won't even compile because `myView` is not a valid identifier. Also, you are not talking about "global variables" here. You are asking about instance variables (ivars) and properties. – Ole Begemann Mar 15 '12 at 15:08
  • 1
    See this answer http://stackoverflow.com/questions/8576593/objective-c-memory-management-of-instance-members/8576760#8576760 – Nick Bull Mar 15 '12 at 15:13
  • Here are some other similar Q's: [Why would you use an ivar?](http://stackoverflow.com/questions/9086736/why-would-you-use-an-ivar). And [iOS: must every iVar really be property?](http://stackoverflow.com/questions/5031230/ios-must-every-ivar-really-be-property). – Sam Mar 15 '12 at 15:26

4 Answers4

4

In the first case, your instance variable (or ivar) myView is private to the class and cannot be accessed by another class.

In the second case, you have provided a property that allows other classes to access your ivar via synthesized accessors. The alternative to declared properties is to write your own accessor methods. The @synthesize notation does that for you.

See Apple documentation on declared properties

FluffulousChimp
  • 9,157
  • 3
  • 35
  • 42
  • So the only difference is that the second one is public?? – Antonio MG Mar 15 '12 at 15:05
  • And one small question (I will give this one as answered, anyway) what is the difference between declaring the private vars in the .m or in the .h? – Antonio MG Mar 15 '12 at 15:07
  • Well technically, in the second case the ivar is still private but you've provided public accessors via the property. Now, it is possible to declare ivars `@public`, `@private` (the default), or `@protected` (available to subclasses) - but as a rule `@public` is never used because it breaks encapsulation. – FluffulousChimp Mar 15 '12 at 15:09
  • I believe ivars declared in the the implementation file are not available to subclasses. I believe that is the only difference. Also properties can be declared in a class extension to create private properties. I use that less now that we have ARC. – FluffulousChimp Mar 15 '12 at 15:13
4

ALWAYS create a @property for every data member and use self.name to access it throughout your class implementation. NEVER access your own data members directly.

Here are some of the reasons to use Properties:

  • Properties enforce access restrictions (such as readonly)
  • Properties enforce memory management policy (retain, assign)
  • Properties are (rarely) used as part of a thread safety strategy (atomic)
  • Properties provide the opportunity to transparently implement custom setters and getters.
  • Having a single way to access instance variables increases code readability.

You can also check out: The Code Commandments: Best Practices for Objective-C Coding

Sam
  • 26,946
  • 12
  • 75
  • 101
Injectios
  • 2,777
  • 1
  • 30
  • 50
  • heh, i wish you would be russian so that i could share with you one of the latest bash-org quotes about object-oriented vs low-level address offsets (not even ivars :) ) programming in very, very, i mean it, very busy computing. – A-Live Mar 15 '12 at 15:20
  • @A-Live google can translate pages (to a degree). You should post the link. :D – Sam Mar 15 '12 at 15:25
  • @Sam here you go :) http://ithappens.ru/story/8584 and the translated link: http://translate.google.com/translate?sl=ru&tl=en&js=n&prev=_t&hl=en&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Fithappens.ru%2Fstory%2F8584&act=url – A-Live Mar 15 '12 at 15:28
  • @A-Live Neat read. Properties certainly don't fit the bill for every situation. Still, surprising it makes that big a difference for that particular circumstance. Makes me wonder if without using Mutex's or some locking mechanism (if there is threading / other operations going on) if some error will still sneak in. I didn't fully follow what user was trying to do, but its not a bad point that sometimes you need to optimize as much as possible. – Sam Mar 15 '12 at 15:38
  • (or if you've subclassed the `description` method of an NSManagedObject) – deanWombourne Mar 15 '12 at 17:08
3

Synthesize makes you getter and setter methods which are called automatically depending on whether you try read or write the value. For the myView property:

myView = newView1; // using direct ivar access
myobject.myView = newvew1; // eq [myobject setMyView:newvew1]; where setMyView: is generated for you automatically with respect to assign/retain, the same for reading:
newvew1 = myobject.myView; // newvew1 = [myobject myView:newvew1];

the generated getter/setter names are customizable with setter=/getter=, if you don't need setter use readonly.

There's no way you can forbid other classes to use synthesized getter and setter, the ivars are @protected by default and if you want to provide other classes an access to the ivars, you can declare them under @public:

@interface myClass (){

   UIImageView *myView; // this is protected

   @public
   UIImageView *myPublicView; // this is public    
}
A-Live
  • 8,904
  • 2
  • 39
  • 74
1

In your first example you access your ivar directly and changing its content. In your second example (the property) an ivar has been created automatically to back the property and all your calls to set and get the property are sent as messages (like: [self setMyView:[[UIImageView alloc] initWithFrame:CGrectMake(0,0,100,100)]];). The accessor methods are also created automatically. This means that you are now following KVC/KVO protocols. For more on the benefits of this design see here

Alladinian
  • 34,483
  • 6
  • 89
  • 91