我很困惑为什么有些类声明属性但不声明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?
答案 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:
当今天编写的代码不需要以旧的运行时为目标时,您应该从属性中合成您的ivars(首选),或者如果您需要与属性无关的ivars,您应该在类中声明它们延期或@implementation
。这样做的主要原因是头文件记录了您的类的公共API,并且不应包含任何不公开的API。 Ivars不公开,因此不应该在头文件中。