Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios objective-c中的本地声明之间有什么区别_Ios_Objective C_Local_Declaration - Fatal编程技术网

Ios objective-c中的本地声明之间有什么区别

Ios objective-c中的本地声明之间有什么区别,ios,objective-c,local,declaration,Ios,Objective C,Local,Declaration,这些声明之间的区别是什么,让我们称之为红色和橙色: 赞成,反对 红色的集合是属性,橙色的集合是实例变量 属性声明告诉编译器定义一个getter方法,可能还有一个setter方法。(如果属性为只读,则没有setter方法。) 在较新版本的Objective C中,声明属性还会创建一个用于保存属性值的实例变量。按照惯例,实例变量与属性具有相同的名称,但前缀为“u”。有一种方法可以更改实例变量的名称,但是现在让我们忽略它 物业管理局: @property (nonatomic, strong) NSS

这些声明之间的区别是什么,让我们称之为红色和橙色: 赞成,反对


红色的集合是属性,橙色的集合是实例变量

属性声明告诉编译器定义一个getter方法,可能还有一个setter方法。(如果属性为只读,则没有setter方法。)

在较新版本的Objective C中,声明属性还会创建一个用于保存属性值的实例变量。按照惯例,实例变量与属性具有相同的名称,但前缀为“u”。有一种方法可以更改实例变量的名称,但是现在让我们忽略它

物业管理局:

@property (nonatomic, strong) NSString *foo;
将有一个getter方法:

- (NSString *) foo;
和setter方法

- (void) setFoo: (NSString *) foo;
这使您能够使用如下代码:

NSString *aString = self.foo;

(调用getter的两种不同、同样有效的方法)

并调用setter

self.foo = @"a string";

(调用setter的两种不同、同样有效的方法)

当您想要创建一个公共接口来从外部获取和设置类中的值时,属性非常有用。如果将属性声明为“原子”,编译器将向getter和setter添加额外的代码,以便对属性的读写是“线程安全的”,并且可以从后台线程访问

在ARC之前,属性也是管理保留和释放的一种非常干净的方式。您将属性声明为“retain”,编写setter是为了保留传入的对象。这在ARC中不是什么问题,因为系统会为您处理保留和释放

还可以编写一个自定义getter或setter方法来调用您自己的代码,而不是编译器编写的代码。您可以使用它来做一些事情,如日志信息、发送更改通知、更新标签等。您只需向.m文件中添加一个方法体,该方法体与getter或setter具有相同的方法签名,编译器使用该方法而不是自动生成的方法

正如我之前所说,守则:

self.foo = @"a string";

[self setFoo: @"a string"];
并调用setter方法。setter方法设置内部实例变量\u foo

然而,代码

_foo = @"a string"; 

直接更改实例变量,而不调用setter。如果您确实定义了一个属性,那么应该使用它而不是实例变量。

Objective-c使用起来很简单……而且很繁琐。您将为一个类(橙色)声明实例变量,然后(通常)为每个类定义2个方法,一个是让外部类可以将每个实例变量设置为新值,另一个是返回ivars值以便外部对象可以读取它。Aka,你必须为每个ivar编写一个getter和setter。接口中有两行代码,实现文件有时大约有10行代码

然后是属性,用@property声明。街上到处都是欢乐和饮酒的场面。这些单独的@property行告诉编译器为您编写这些方法,包括正确的内存管理代码,甚至是互斥锁代码(取决于您在声明@property时指定的内容)

有很多历史,但是现在,随着自动引用计数的出现,只有当您想要将ivar公开,并在实现文件中声明您的私有ivar时,在接口中使用@properties才有意义

最后,@property不仅告诉编译器实现getter和setter,而且还自动提供一个具有相同名称但前缀为下划线的实例变量(仅当您启用了隐式属性合成…更多历史记录时)


所以,这就是区别@属性告诉编译器为您编写代码(本质上)。它实际编写的代码通过声明@property的所有不同方式进行修改。

+1表示“仅在接口中使用@properties才有意义”(使用ARC)。我还是不知道为什么人们总是使用私人财产nowadays@LucasEduardo属性使使用KVO更加容易。这是私人IVAR的主要好处之一。它还提供了适当的封装,允许像延迟加载之类的事情。我确实知道它的好处,但我认为它们通常是间接的。我只是不喜欢使用私有属性(!=iVars),除非你有很好的理由。你能解释一下或者举一个简单的例子来解释最后一行吗?如果在不调用setter的情况下更改实例变量会有所不同。@BishalGhimire如果您有setter的自定义实现,直接设置ivar将绕过该额外功能。对于给定的情况,这可能是或可能不是理想的。当您直接设置ivar而不是使用属性时,您也会错过使用KVO的机会。
[self setFoo: @"a string"];
_foo = @"a string";