ios - @property 实际上在幕后做了什么……使用 self.和 self-> 和 _ 下划线

标签 ios objective-c properties

我仍在努力解决@implementation 部分中的语法错误。

所以,我想了解使用 @property 和不使用 @property 之间的区别。

第一种情况是一个 @interface,我在 {} 中声明了一些变量。

//ViewController.h


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

@interface ViewController : UIViewController
{
    Student *stObj;
}

并且,我尝试使用多个标识符(_(下划线)、self.、self->、无)来引用 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!



 }

第二种情况是我使用@property的一个@interface

@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!

所以,正如你所看到的,我必须假设的是那个 self 。和 _(下划线)有效并且看起来很相似......?

问题是@property实际上做了什么导致了不同的结果..?

感谢您阅读我的问题,如果我做错了什么,请纠正我。


最佳答案

首先,让我们解释一下属性是什么:它基本上是一组方法,通常用于访问实例变量。这是一个过于简单(并且有点不正确)的解释,但在大多数情况下就足够了。

您可以使用@synthesize关键字定义实例变量的名称,如下所示:

@property Type foo;

...

@synthesize foo = somethingElse;

在这种情况下,编译器将生成:

  • 名为 somethingElse 且类型为 Type 的实例变量。
  • 读取名为 foo 的变量的方法:它仅返回变量 somethingElse 的内容。
  • 编写变量的方法,称为 setFoo::它设置变量 somethingElse 的内容,并负责通知键值观察者。

如果不指定@synthesize语句,编译器会自动生成一个实例变量,其属性名以下划线为前缀。因此,如果您的属性名为 foo,则自动创建的实例变量称为 _foo

当你这样做时:

@property Student *stObj;

(没有@synthesize)编译器生成:

  • Student * 类型的实例变量 _stObj
  • 名为 stObj 的方法,用于读取变量 _stObj 的内容。
  • 名为 setStObj: 的方法,用于写入变量 _stObj 的内容。

接下来,访问实例变量:如果范围允许(例如 _foo),您可以直接通过名称访问它们,也可以通过 ->< 访问它们 取消引用运算符,如 self->_foo 中所示。后者还允许您访问其他对象的公共(public)实例变量,如 otherObject->_foo 中所示。不过,除非您真正知道自己在做什么,否则不要这样做。

最后但并非最不重要的一点是点符号。编写 obj.method 与编写 [obj method] 相同,编写 obj.method = value 与编写 [ 相同obj setMethod:值]。也就是说,点表示法是方法调用的较短语法。 (我倾向于避免它,因为它也是访问结构成员的表示法,但这只是我的想法。)

有了这些知识,您的示例就很容易解释:

在第一个示例中:

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];

关于ios - @property 实际上在幕后做了什么……使用 self.和 self-> 和 _ 下划线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22398609/

相关文章:

java - 如何找出在 Linux 机器中定义的属性名称?

ios - 从父类(super class)访问子类属性

ios - 从 xib 到 Storyboard的后退按钮

iphone - 使 NSObject 的自定义类可序列化

ios - 手写绘图有点晚,就像我手指的回声 ios objective c

function - typescript 接口(interface) : function as property - or - this in interface implementations

ios - 在特定 View Controller 中隐藏状态栏

iphone - 网址为:(空),但请求字符串不为空

ios - 用其他字符替换字符串中的字符(唯一的通配符值)

c# - 您可以通过 Property setter 实例化对象吗?