iOS自动@synthesize而不创建ivar

Posted

技术标签:

【中文标题】iOS自动@synthesize而不创建ivar【英文标题】:iOS automatic @synthesize without creating an ivar 【发布时间】:2012-10-07 16:18:31 【问题描述】:

如果我有一个 @property,我不想通过 ivar 支持它,我只是省略了 @synthesize 并使用返回计算值的手动 getter。

但是,现在从 Xcode 4.4 开始,如果我不指定 @synthesize,编译器会自动生成它。这是否意味着即使我不需要/使用它也会生成ivar

我最终可以通过使用dynamic 来强制不自动合成。然而这是错误的,因为@dynamic 应该用于在getter and setter are implemented somewhere else or during runtime 时关闭警告。

【问题讨论】:

它是只读属性吗?如果没有,它可能会为它生成一个 setter 和一个 ivar。 @Thilo 只读属性仍然有 iVar,毫无疑问。 @synthesize 的全部意义在于为您创建 iVar 如果你没有 ivar,你应该在哪里存储属性的支持值? “你应该在哪里存储属性的支持值”:返回计算值的手动 getter 如果你提供了所有的getter(和用于读写的setter),那么不会自动生成ivar。如果缺少一种方法,它必须 - 否则它无法创建该方法。 【参考方案1】:

在处理这个问题时,我注意到了以下行为。

    如果您有读写属性,但没有@synthesize,有getter 但没有setter,那么它将生成iVar。 如果你有读写属性,没有@synthesize,没有getter,有setter,那么它会生成iVar。 如果您有读写属性,但没有 @synthesize 并且同时有 getter 和 setter,则不会生成 iVar。 如果您有只读属性、没有@synthesize 并且没有getter,那么它将生成iVar。 如果你有一个只读属性,没有@synthesize 并且有一个getter,那么它不会生成iVar。

据此,我认为一般规则是,如果您没有@synthesize,并且拥有完全实现该属性所需的所有方法,则假定它是动态的并且不会生成 iVar。

无论如何,如果您想确保不生成 iVar,请将其声明为 @dynamic


澄清@dynamic

来自Declared Properties 中的The Objective-C Programming Language:

您使用 @dynamic 关键字告诉编译器您将通过直接提供方法实现或在运行时使用其他机制(例如动态加载代码或动态方法解析)来履行属性所隐含的 API 协定。

在我看来,即使您直接实现 getter 和 setter,也可以将属性标记为 @dynamic。

【讨论】:

根据这里的各种 cmets ***.com/questions/1160498/… @dynamic 的使用是错误的,因为我提供了 getter 和 setter。 嗯,这似乎是正确的!很高兴听到它这么简单! 如果您实现了所有必需的访问器方法(只读属性的 getter,读写属性的 getter + setter),则不会自动合成属性。 -- ***.com/a/16772676/456536 @iwill 是的,我得出了同样的结论:如果你没有@synthesize,并且拥有完全实现该属性所需的所有方法,那么它被认为是动态的并且不生成 iVar。没有来自 Apple、llvm 或 clang 的文档说明这一事实。所以,我展示了我的作品。您链接到的答案没有提供来源,而是将其断言为事实而没有任何解释。那不是我的风格。 @JefferyThomas 干得好,保持你的风格。但我认为这将是一个更好的答案——“如果你没有@synthesize,并且拥有完全实现该属性所需的所有方法,那么它被假定为动态的并且不会生成 iVar。有没有来自 Apple、llvm 或 clang 的文档说明这一事实。”。【参考方案2】:

如果将属性标记为只读,自己实现getter,好像不会创建iVar。

接口声明:

@property (nonatomic, readonly) BOOL myBoolProp;

执行:

- (BOOL)myBoolProp 
    return true;

试试这个:

- (void)viewDidLoad 
    [super viewDidLoad];
    _myBoolProp = true;

会产生错误:Use of undeclared identifier '_myBoolProp'

删除自定义 getter 方法也会删除错误,似乎表明 iVar 现已生成。

【讨论】:

仅仅因为您无法使用您期望的名称引用 iVar,并不意味着它不存在。我强烈建议使用运行时确保不会实际生成任何 iVar。 在 WWDC 2012 演示文稿“Modern Objective C”中指出,对于只读属性“如果您让我们合成 getter,您将获得一个实例变量,否则您不会”跨度> 【参考方案3】:

是的 - iVar 仍然由 clang 生成(不是 Xcode,因为它是 IDE,clang 是真正重要的编译器)。

如果您真的不想要 iVar 并且不想要实现,那么可以使用有点过时的 @dynamic 关键字来满足您的需求,或者您可以在协议中指定属性,这不会让它自动合成:

// .h
@property (nonatomic, retain) NSObject *someProp;

//.m
@dynamic someProp; // no iVars generated

// other solution
@protocol MyObjectProtcol<NSObject>

@property (nonatomic, retain) NSObject *someProp;

@end

// now, when you implement the MyObjectProtocol protocol, the property won't auto-synthesize.

【讨论】:

那么,@Jeffery 的观察不正确? (如果你有一个只读属性,没有合成并且有一个getter,那么它不会生成iVar。) @Thilo 这不是指杰弗里所说的边缘案例。这是指 OP 中概述的单一情况。所以,在大多数情况下,他所说的都是正确的。 根据这里的各种 cmets ***.com/questions/1160498/… @dynamic 的使用是错误的,因为我提供了 getter 和 setter。 @znq 这不是“错误的”。最初的用例是这样的,是的,但是语言已经发展,@dynamic 变得更加有趣,如果你不希望 iVar 到处飞。

以上是关于iOS自动@synthesize而不创建ivar的主要内容,如果未能解决你的问题,请参考以下文章

iOS 开发小记

iOS 自动归解档

IOS 关键字self,super,copy, retain, assign , readonly , readwrite, nonatomic@synthesize@property@dyna

Objective-C 是 @synthesize 是必需的还是可选的?

iOS - 在指定的初始化程序中分配给 iVar 导致 nil iVar

iOS-关于@property和@synthesize