Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
581 views
in Technique[技术] by (71.8m points)

ios - what does @property actually do behind the scene..with usage of self. and self-> and _ underscore

I'm still struggling with the syntax errors in @implementation section.

So, I want to understand the difference between using @property and not.

First case is would be one @interface where i declared some variable in {}.

//ViewController.h


#import <UIKit/UIKit.h>
#import "Student.h"       // just class i made

@interface ViewController : UIViewController
{
    Student *stObj;
}

And, i'm trying to refer to stObj pointer using several identifier ( _(underscore), self. , self->, nothing)

//  ViewController.m


#import "ViewController.h"

@interface ViewController () // just leaving this code cuz i haven't study what it is :)

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    stObj = [[Student alloc]init ];        //no error

    //self->stObj = [[Student alloc]init];  //no error
    //self.stObj = [[Student alloc]init];   //error!
    //_stObj = [[Student alloc]init];       //error!



 }

Second case is would be one @interface where i use @property

@interface ViewController : UIViewController

@property Student *stObj;

@end

and do the same thing like above.

stObj = [[Student alloc]init ];        //error
//self->stObj = [[Student alloc]init];  //error
//self.stObj = [[Student alloc]init];   //no error!
//_stObj = [[Student alloc]init];       //no error!

SO, as you can see what i had to assume was that self. and _ (underscore) worked and seems similar ...?

The Question is that what @property actually does causing different result..?

Thank you for reading my question and if i'm doing something wrong please correct me.


See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

First, let's explain what a property is: it's basically a set of methods, usually for accessing an instance variable. That's an overly simple (and slightly incorrect) explanation but it will suffice most of the time.

You can define the name of the instance variable with the @synthesize keyword, as in:

@property Type foo;

...

@synthesize foo = somethingElse;

In this case, the compiler will generate:

  • An instance variable called somethingElse of type Type.
  • A method to read the variable called foo: it just returns the content of the variable somethingElse.
  • A method to write the variable called setFoo:: it sets the content of the variable somethingElse and takes care of notifying key-value observers.

If you don't specify a @synthesize statement, the compiler will automatically generate an instance variable with the property name prefixed by an underscore. So if your property is named foo, the automatically created instance variable is called _foo.

When you do:

@property Student *stObj;

(without a @synthesize) the compiler generates:

  • An instance variable _stObj of type Student *.
  • A method called stObj that reads the content of the variable _stObj.
  • A method called setStObj: that writes the content of the variable _stObj.

Next, access to instance variables: you can either access them by their name directly, if the scope allows it (like _foo), or you can access them via the -> dereference operator as in self->_foo. The later also allows you to access public instance variables of other objects, as in otherObject->_foo. Don't do this unless you really know what you're doing, though.

Last but not least, the dot-notation. Writing obj.method is the same as writing [obj method] and writing obj.method = value is the same as writing [obj setMethod:value]. That is, the dot-notation is a shorter syntax for a method call. (I tend to avoid it since it's also the notation for access struct members, but that's just me.)

With that knowledge, your examples are easy to explain:

In your first example:

stObj = [[Student alloc] init]; // Access to instance variable. OK.
self->stObj = [[Student alloc]init]; // Access to instance variable. OK

// The next statement is the same as [self setStObj:[[Student alloc]init];
// But there is no method named setStObj: defined.
self.stObj = [[Student alloc]init];
// Trying to access a variable that doesn't exist. It's called stObj instead.
_stObj = [[Student alloc]init];

In your second example:

// There is no variable stObj, it's called _stObj in this case.
stObj = [[Student alloc]init ]; // That's why this fails.
self->stObj = [[Student alloc]init]; // And this as well.

// The property has created the `setStObj:` method, so the next
// line succeeds.
self.stObj = [[Student alloc]init];
// The property has created the _stObj instance variable, so the
// next line succeeds.
_stObj = [[Student alloc]init];

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...