简体   繁体   中英

Difference between using properties and not for accessing ivars

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?

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

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

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    
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM