我对为什么某些类声明一个属性却不声明一个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:
今天编写不需要面向旧运行时的代码时,您应该从属性中合成ivars(首选),或者如果您不需要与属性绑定(bind)的ivars,则应在类扩展中或在其上声明它们。您的
@implementation
。这样做的主要原因是因为头文件记录了您的类的公共(public)API,并且不应包含任何非公共(public)的内容。 Ivar不是公共(public)的,因此不应放在头文件中。关于objective-c - 属性与实例变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12015307/