请在Objective C中解释Getter和Setters

时间:2012-05-03 05:52:13

标签: objective-c setter getter

  

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

我是初学者。我刚刚开始学习iOS过去两个月,我没有任何编程背景。 (虽然有点Java)。任何人都可以在Objective C中解释什么是getter和setter?它们有什么用?为什么我们使用@property@synthesize

3 个答案:

答案 0 :(得分:80)

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。如果您希望访问器执行比仅从某个实例变量存储/检索值更复杂的任何操作,则必须自己编写它们。

希望这一切都有意义。

答案 1 :(得分:5)

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

“setter”最常用于面向对象的编程,与封装原理保持一致。根据这个原则,类的成员变量是私有的,以隐藏和保护它们免受其他代码的攻击,并且只能通过公共成员函数进行修改,该函数将所需的新值作为参数,可选地对其进行验证,并修改私人成员变量。

“setter”通常附带一个“getter”(也称为访问器),它返回私有成员变量的值。

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

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

答案 2 :(得分:3)

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

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

祝你好运。