属性与实例变量

时间:2012-08-18 02:19:26

标签: objective-c object properties ivar

我很困惑为什么有些类声明属性但不声明ivar,反之亦然。

声明实例变量同时将其声明为属性是否是标准做法?

示例:

@interface AppDelegate : NSObject <UIApplicationDelegate>
{
    UIWindow *window;
    UINavigationController *navigationController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

只是在声明一个类的ivar以使其成为属性时的标准做法?

我知道@property创建了自己的拉长的setter(和@synethesize的getter),但为什么它也需要成为一个ivar?

1 个答案:

答案 0 :(得分:14)

没有。

在过去,需要在@interface中声明ivars。对于PPC和i386(即32位英特尔)目标,这实际上仍然是正确的。这是因为fragile base class problem,它要求所有子类都知道它们超类的确切大小。因此,ivars需要在@interface中,否则任何人都不能继承该类。

随着迁移到x86_64和ARM,与obj-c 2.0一起解决了脆弱的基类问题。通过此修复,不再需要在编译时知道类大小,而是可以将其延迟到运行时。因此,ivars可以在其他地方宣布。值得注意的是,现在可以从@property(更具体地说,实现中的@synthesize行)合成ivar。在Clang中,它们也可以在类扩展块(看起来像@interface ClassName ())或直接在@implementation上声明。

今天,有3个理由可以找到@interface块中声明的ivars:

  1. 旧代码(或具有旧习惯的程序员)尚未更新以利用隐藏ivar声明的能力。
  2. 需要在PPC或i386上运行的代码。
  3. 代码,无论出于何种原因,都希望他们的ivars公开。绝不应该这样。
  4. 当今天编写的代码不需要以旧的运行时为目标时,您应该从属性中合成您的ivars(首选),或者如果您需要与属性无关的ivars,您应该在类中声明它们延期或@implementation。这样做的主要原因是头文件记录了您的类的公共API,并且不应包含任何不公开的API。 Ivars不公开,因此不应该在头文件中。