我对为什么某些类声明一个属性却不声明一个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?

最佳答案

没有。

在过去,必须在@interface中声明ivars。对于PPC和i386(即32位Intel)目标,实际上仍然是这样。这是因为fragile base class problem,它要求所有子类都知道其父类(super class)的确切大小。因此,ivars需要包含在@interface中,否则没人可以继承该类。

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

今天,有3个原因可以找到在@interface块中声明的ivars:

  • 尚未更新以利用隐藏ivar声明的功能的旧代码(或具有旧习惯的程序员)。
  • 需要在PPC或i386上运行的代码。
  • 无论出于何种原因,都希望其ivars公开。决不是这种情况。

  • 今天编写不需要面向旧运行时的代码时,您应该从属性中合成ivars(首选),或者如果您不需要与属性绑定(bind)的ivars,则应在类扩展中或在其上声明它们。您的@implementation。这样做的主要原因是因为头文件记录了您的类的公共(public)API,并且不应包含任何非公共(public)的内容。 Ivar不是公共(public)的,因此不应放在头文件中。

    关于objective-c - 属性与实例变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12015307/

    10-10 10:30