objective-c - 属性与实例变量

标签 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?

最佳答案

不是。

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

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

今天,您发现 @interface block 中声明的 ivar 有 3 个原因:

  1. 尚未更新以利用隐藏 ivar 声明功能的旧代码(或有旧习惯的程序员)。
  2. 需要在 PPC 或 i386 上运行的代码。
  3. 编写代码,无论出于何种原因,都希望他们的 ivar 公开。这种情况永远不应该发生。

当今天编写不需要以旧运行时为目标的代码时,您应该从您的属性中合成您的 ivar(首选),或者如果您需要与属性无关的 ivar,您应该在类中声明它们扩展名或在您的@implementation 上。这样做的主要原因是因为头文件记录了类的公共(public) API,不应包含任何非公共(public)的内容。 Ivars 不是公开的,因此不应该在头文件中。

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

相关文章:

javascript - 如何对对象数据进行求和和分组?

JavaScript - 点击图片

javascript - 使用 Javascript 或 jQuery 将数组字符串转换为对象

python - 关于 python 中的属性类

java - 使用 Spring Boot 构建自己的配置服务器

iphone - 在Objective-C中从类名的NSString创建对象

ios - "A GKScore must specify a leaderboard."

javascript - 这些是子属性吗?什么是正确的术语?

ios - AFNetworking 禁用缓存

ios - 这个声明是什么意思?