【问题标题】:Please explain Getter and Setters in Objective C [duplicate]请解释Objective C中的Getter和Setter [重复]
【发布时间】:2012-05-12 15:22:06
【问题描述】:

可能重复:
Setters and Getters (Noobie) - iPhone SDK

我是这里的初学者。我最近两个月才开始学习 iOS,没有任何编程背景。 (虽然一点点Java)。谁能解释一下Objective C中的getter和setter是什么?它们有什么用?为什么我们使用@property@synthesize

【问题讨论】:

    标签: objective-c setter getter


    【解决方案1】:

    Getter 是一种在您每次访问(读取值)属性(用@property 声明)时调用的方法。无论该方法返回什么都被认为是该属性的值:

    @property int someNumber;
    

    ...

    - (int)someNumber {
        return 42;
    }
    

    ...

    NSLog("value = %d", anObject.someNumber); // prints "value = 42"
    

    Setter 是一种在每次更改属性值时都会调用的方法。

    - (void)setSomeNumber: (int)newValue { // By naming convention, setter for `someValue` should 
                                        // be called `setSomeValue`. This is important!
        NSLog("someValue has been assigned a new value: %d", newValue);
    }
    

    ...

    anObject.someNumber = 19; // prints "someValue has been assigned a new value: 19"
    

    通常从 getter 返回相同的值并在 setter 中打印新值并没有多大意义。要实际存储一些东西,你必须在你的类中声明一个实例变量(ivar):

    @interface SomeClass : NSObject {
        int _someNumber;
    }
    

    并让访问器(getter 和 setter 的统称)存储/检索它的值:

    - (int)someNumber {
        return _someNumber;
    }
    
    - (void)setSomeNumber:(int)newValue {
        _someNumber = newValue;
    }
    

    ...

    SomeClass *anObject = [[SomeClass alloc]init];
    anObject.someNumber = 15;
    NSLog(@"It's %d", anObject.someNumber); // prints "It's 15"
    

    好的,现在该属性的行为就像通常的变量一样。写这么多代码有什么意义?

    首先,从现在开始,您可以向访问器添加一些额外的代码,这些代码将在每次访问或更改属性时执行。这样做有多种原因,例如我可能想要进行某种隐藏计算,或者更新对象的状态、缓存内容等。

    其次,Cocoa 中有很酷的机制,称为键值编码 (KVC) 和键值观察 (KVO)。它们取决于属性。您可以在开发人员库中了解它们:KVC Programming GuideKVO Programming Guide。不过,这些都是高级主题。

    最后,Objective C 中没有对象的静态分配。所有对象都是动态分配的 (reason)。如果您想将对象指针保留在实例变量中(而不是属性),则每次为 ivar 分配新值时都必须手动执行所有内存管理(Automatic Reference Counting 开启时不正确)。使用属性,您可以在访问器中添加一些内存管理代码,让您的生活更轻松。

    我认为这种解释对于不熟悉 Objective C 内存管理的人来说没有多大意义,因此,要么阅读一些关于它的真实文档/教程,要么只使用属性(而不是实例变量),直到你以一种或另一种方式了解所有细节。就个人而言,我不喜欢第二种选择,但这取决于你。

    您可以使用@synthesize 使编译器自动为您生成基本访问器和底层实例变量。而不是上面的代码(-(int)someNumber-(void)setSomeNumber:)你可以写

    @synthesize someNumber = _someNumber; // = _someNumbers tells compiler 
                                          // to name the instance variable `_someNumber`. 
                                          // You could replace it with = `_somethingElse`, of
                                          // course, but that's an ill idea.
    

    这一行会为您生成int _someNumber 变量、someNumber getter 和setSomeNumber setter。如果您希望访问器执行比存储/检索某个实例变量的值更复杂的操作,则必须自己编写它们。

    希望这一切都有意义。

    【讨论】:

      【解决方案2】:

      “Getters”和“setters”用于控制对变量(字段)的更改。

      “setter”最常用于面向对象的编程中,符合封装原则。根据这一原则,将类的成员变量设为私有以隐藏和保护它们不受其他代码的影响,并且只能由公共成员函数修改,该函数将所需的新值作为参数,可选地对其进行验证,并修改私有成员变量。

      “setter”通常伴随着“getter”(也称为访问器),它返回私有成员变量的值。

      Getter/Setter 方法也可以在非面向对象的环境中使用。在这种情况下,对要修改的变量的引用与新值一起传递给方法。在这种情况下,编译器无法限制代码绕过 getter/setter 方法并直接更改变量。开发人员有责任确保仅通过这些方法修改变量,而不是直接修改。

      在支持它们的编程语言中,属性提供了一种方便的替代方案,而不会放弃封装的实用性。

      【讨论】:

        【解决方案3】:

        大多数面向对象语言中的属性“getters”和“setters”都围绕类实例的私有成员提供“外部”或用户界面。一些 OO 批评者将它们称为“语法糖”,但归根结底是,您的类的使用者将使用这些以编程方式控制的接口,而不是访问实际 em> 私人成员自己。这样,您可以(例如)保护私有变量不接收无效或超出范围的值,或者通过仅提供 getter 但不提供 setter 将属性设为只读。更有趣的是,getter 和 setter 可以包装在您的类中未原生保留的属性,但可能(例如)基于其他实例成员进行计算。

        Getter 和 setter 肯定不是 Objective-C 独有的。如果您继续使用其他 OO 语言进行编程,您会在 C#、Java 和其他语言中找到它们的风格。

        祝你好运。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-25
          • 1970-01-01
          • 1970-01-01
          • 2023-03-12
          • 2016-11-09
          • 2020-06-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多