所以,我想了解使用@property与否之间的区别.
第一种情况是一个@interface,我在{}中声明了一些变量.
//ViewController.h #import <UIKit/UIKit.h> #import "Student.h" // just class i made @interface ViewController : UIViewController { Student *stObj; }
而且,我试图使用几个标识符(_(下划线),自我,自我>,没有)引用stObj指针
// 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! }
第二种情况是@interface,我使用@property
@interface ViewController : UIViewController @property Student *stObj; @end
和上面做同样的事情.
stObj = [[Student alloc]init ]; //error //self->stObj = [[Student alloc]init]; //error //self.stObj = [[Student alloc]init]; //no error! //_stObj = [[Student alloc]init]; //no error!
所以,你可以看到我必须假设的是那个自我.和_(下划线)工作,似乎相似……?
问题是@property确实造成了不同的结果..?
感谢您阅读我的问题,如果我做错了,请纠正我.
解决方法
您可以使用@synthesize关键字定义实例变量的名称,如下所示:
@property Type foo; ... @synthesize foo = somethingElse;
在这种情况下,编译器将生成:
>名为somethingElse的类型为Type的实例变量.
>一个读取变量foo的方法:它只返回变量somethingElse的内容.
>一个写入变量的方法,名为setFoo :: it设置变量somethingElse的内容,并负责通知键值观察者.
如果未指定@synthesize语句,编译器将自动生成一个实例变量,其属性名称以下划线为前缀.因此,如果您的属性名为foo,则自动创建的实例变量称为_foo.
当你这样做时:
@property Student *stObj;
(没有@synthesize)编译器生成:
> Student *类型的实例变量_stObj.
>一个名为stObj的方法,用于读取变量_stObj的内容.
>一个名为setStObj的方法:写入变量_stObj的内容.
接下来,访问实例变量:您可以直接通过其名称访问它们,如果范围允许(如_foo),或者您可以通过 – >访问它们.取消引用运算符,如self-> _foo.后者还允许您访问其他对象的公共实例变量,如otherObject-> _foo.但是,除非你真的知道自己在做什么,否则不要这样做.
最后但并非最不重要的是,点符号.编写obj.method与编写[obj方法]相同,编写obj.method = value与编写[obj setMethod:value]相同.也就是说,点符号是方法调用的较短语法. (我倾向于避免它,因为它也是访问结构成员的符号,但那只是我.)
有了这些知识,您的示例很容易解释:
在你的第一个例子中:
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];