【问题标题】:what is the difference between local declarations in objective-c [duplicate]Objective-C中的本地声明有什么区别[重复]
【发布时间】:2013-09-11 18:41:25
【问题描述】:

这些声明之间有什么区别,我们称它们为红色和橙色: 利弊?

【问题讨论】:

    标签: ios objective-c local declaration


    【解决方案1】:

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

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

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

    属性 foo:

    @property (nonatomic, strong) NSString *foo;
    

    会有一个getter方法:

    - (NSString *) foo;
    

    还有一个setter方法

    - (void) setFoo: (NSString *) foo;
    

    这使您可以使用这样的代码:

    NSString *aString = self.foo;
    

    NSString *aString = [self foo];
    

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

    并调用设置器

    self.foo = @"a string";
    

    [self setFoo: @"a string"];
    

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

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

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

    也可以编写自定义的 getter 或 setter 方法来调用您自己的代码,而不是编译器编写的代码。您可以使用它来执行日志信息、发送有关更改的通知、更新标签等操作。您只需将方法主体添加到具有与 getter 或 setter 相同的方法签名的 .m 文件中,编译器就会使用它方法而不是自动生成的方法。

    正如我之前所说,代码:

    self.foo = @"a string";
    

    一样
    [self setFoo: @"a string"];
    

    并调用setter方法。 setter 方法设置内部实例变量 _foo。

    但是代码

    _foo = @"a string"; 
    

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

    【讨论】:

    • 你能解释或举一个简单的例子来解释最后一行吗?在不调用 setter 的情况下更改实例变量会有所不同。
    • @BishalGhimire 如果您有自定义的 setter 实现,直接设置 ivar 将绕过该额外功能。对于给定的情况,这可能是理想的,也可能不是理想的。当您直接设置 ivar 而不是使用属性时,您也会错过使用 KVO。
    【解决方案2】:

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

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

    有很多历史,但是现在,有了自动引用计数,只有在你想要公开 ivar 并在你的实现文件中声明你的私有 ivar 时,在你的界面中使用 @properties 才有意义。

    最后,并不是说@property 不仅告诉编译器实现你的getter 和setter,它还自动提供一个同名的实例变量,但前缀为下划线(这只有在你有属性的隐式合成时启用...更多历史记录)

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

    【讨论】:

    • +1 表示“只有在你的界面中使用 @properties 才有意义”(使用 ARC)。我仍然不知道为什么人们现在继续使用私有财产
    • @LucasEduardo Properties 使使用 KVO 变得更加容易。这是私有 ivars 的主要好处之一。它还提供适当的封装,允许延迟加载等。
    • 我确实知道好处,但我认为它们通常是间接的。我只是不喜欢使用私有属性(!= iVars),除非你有充分的理由。
    猜你喜欢
    • 2011-11-09
    • 2022-01-16
    • 2014-06-26
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多