@property在幕后实际上是做什么的.和自我>和_下划线 [英] what does @property actually do behind the scene..with usage of self. and self-> and _ underscore
问题描述
我仍然在@implementation部分中遇到语法错误.
I'm still struggling with the syntax errors in @implementation section.
所以,我想了解使用@property和不使用@property之间的区别.
So, I want to understand the difference between using @property and not.
第一种情况是一个@interface,我在{}中声明了一些变量.
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;
}
而且,我正在尝试使用多个标识符(_(下划线),self.,self->,什么都没有)来引用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!
}
第二种情况是我使用@property的一种@interface
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 ...?
问题是@property实际上会导致不同的结果吗??
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.
推荐答案
首先,让我们解释一下属性是什么:它基本上是一组方法,通常用于访问实例变量.这是一个过于简单(略有错误)的解释,但在大多数情况下就足够了.
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.
您可以使用@synthesize
关键字定义实例变量的名称,如下所示:
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:
- 类型为
Type
的名为somethingElse
的实例变量. - 一种读取名为
foo
的变量的方法:它仅返回变量somethingElse
的内容. - 一种写名为
setFoo:
的变量的方法:它设置变量somethingElse
的内容并负责通知键值观察者.
- An instance variable called
somethingElse
of typeType
. - A method to read the variable called
foo
: it just returns the content of the variablesomethingElse
. - A method to write the variable called
setFoo:
: it sets the content of the variablesomethingElse
and takes care of notifying key-value observers.
如果未指定@synthesize
语句,则编译器将自动生成实例属性,该实例变量的属性名称以下划线为前缀.因此,如果您的属性名为foo
,则自动创建的实例变量称为_foo
.
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
.
当您这样做:
@property Student *stObj;
(没有@synthesize
)编译器生成:
- 类型为
Student *
的实例变量_stObj
. - 称为
stObj
的方法,该方法读取变量_stObj
的内容. - 称为
setStObj:
的方法,用于写入变量_stObj
的内容.
- An instance variable
_stObj
of typeStudent *
. - A method called
stObj
that reads the content of the variable_stObj
. - A method called
setStObj:
that writes the content of the variable_stObj
.
接下来,访问实例变量:如果范围允许(例如_foo
),则可以直接通过它们的名称访问它们,或者可以像self->_foo
一样通过->
取消引用运算符访问它们.后者还允许您访问其他对象的公共实例变量,如otherObject->_foo
所示.除非您真的知道自己在做什么,否则不要这样做.
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.
最后但并非最不重要的是点符号.写obj.method
与写[obj method]
相同,写obj.method = value
与写[obj setMethod:value]
相同.也就是说,点符号是方法调用的较短语法. (我倾向于避免使用它,因为它也是访问结构成员的表示法,但那只是我.)
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:
在您的第一个示例中:
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];
在第二个示例中:
// 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];
这篇关于@property在幕后实际上是做什么的.和自我>和_下划线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!