iPhone开发中的Objective-C属性

8

Objective-C中属性和实例变量有什么区别?我需要用面向对象的术语来理解。属性声明只是一个方便的包装器(在实现中使用@synthesize)来访问实例变量吗?

谢谢,

codecowboy。

3个回答

7

属性和实例变量是两个完全不同的东西。

实例变量是存储在对象内部的变量,因此每个实例都有自己的实例变量。它通过指针相对于对象指针/ self进行引用(对于现代运行时略微间接,但在功能上等效)。ivars通常是类内部的,且默认情况下只能由类及其子类(@protected)访问。在方法中,它们可以无需限定符就可用,否则它们可以(但很少被使用,通常也不应该)通过间接方式访问,例如obj->ivar。

属性定义了getter和setter(setter是可选的)接口。这就是它所做的全部。它定义了两个公共方法:

- (TYPE) propname;
- (void) setPropname: (TYPE) newPropname;

这些方法被定义为正好如同您声明它们一样,没有多余或少于的部分。这些方法可以使用常规语法([obj propname]和[obj setPropname:n])或者使用现代点语法(obj.propname或obj.propname = n)进行调用。这两种语法选项在语法上有所不同,但它们的行为是相同的,无论这些方法是使用@property声明还是手动声明。
然后,您必须在实现中实现这些方法,可以通过编写自己的方法、使用@synthesize或动态处理缺失的方法来完成。
属性可以由一个ivar(与名称相同或不同(我个人喜欢避免混淆))支持,也可以不支持。它们可以将其值存储在其他地方,也可以从其他数据计算得出。
例如,您可能会有:
@property (nonatomic, readonly) NSString* fullname;

然后实现 - (NSString*) fullname 方法,返回 firstname 和 lastname 的连接字符串。


这正是我困惑的地方。对象实例不也拥有自己的属性吗?我对对象的理解是,它们包含有关状态(数据)和行为(方法)的信息。为什么我需要实例变量和属性?除非我将它们声明为属性,否则实例变量是不可变的吗? - codecowboy
2
属性是外部对象获取和设置数据的接口。实例变量是该对象内部的,尽管可以使用属性、自己的getter/setter方法或通过您创建的其他公共方法间接地暴露给外部对象。 - Marc Charbonneau
1
换句话说,属性声明不会在实例对象中创建任何东西。它只是告诉外部世界如何从对象中获取某些内容。这个内容可能是一个实例变量,也可能是你想为其编写getter和setter方法的任何信息。至于实例变量,它们可以像在C和C++中一样被访问。 - Vagrant

4
我认为你已经非常接近成功了。@property和@synthesize用于访问器声明和实现,其针对已经声明的实例变量。你可以在@property中定义各种属性,以便对其进行控制,使其适用于实例变量。
请看一下“Objective C 2.0已声明属性”

0

属性实例变量的区别在于,被设置为属性的变量可以在另一个类中被访问,而要访问实例变量,则需要先创建该类的对象,然后才能进行访问。 使用 @synthesize 关键字,编译器会为该属性生成相应的setter和getter方法。

- (TYPE)name; - getter方法

- (void)setName:(TYPE)aName; - setter方法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接