iOS automatic @synthesize without creating an ivar
如果我有一个@property,我不想通过ivar来支持它,我简单地省略了@synthesize,并且有手动getter返回一个计算值。
但是,现在,由于xcode 4.4,如果我没有指定@synthesizedo编译器将自动生成它。这是否意味着它还将生成一个ivar,即使我不需要/使用它?
我最终可能会强迫不使用dynamic自动合成。然而,这是错误的,因为如果getter和setter是在其他地方或运行时实现的,那么@dynamic应该用于关闭警告。
- 它是只读属性吗?如果没有,它可能会为它生成一个setter和一个ivar。
- @毫无疑问,Thilo只读属性仍然具有ivar。@synthesize的全部要点是为您创建ivar。
- 我有一个二传手。但是,我不希望创建额外的IVAR。
- 即使有一个定制的getter和没有setter?
- 是的,一个没有IVAR的房产是没有意义的。
- 如果你没有一个IVAR,你应该在哪里存储财产的支持价值?
- "您应该在哪里存储属性的支持值":返回计算值的手动getter
- 如果您提供了所有的getter(和readwrite的setter),那么不会自动生成ivar。如果缺少一个方法,它必须-否则它无法创建该方法。
在我的工作中,我注意到了以下行为。
如果你有读写属性,没有@synthesize,没有getter,也没有setter,那么它将生成ivar。
如果你有一个读写属性,没有@synthesize,没有getter,也没有setter,那么它将生成ivar。
如果您有一个readwrite属性,没有@synthesize,同时有getter和setter,那么它将不会生成ivar。
如果您有一个只读属性,没有@synthesize和getter,那么它将生成ivar。
如果您有一个readonly属性,没有@synthesize和getter,那么它将不会生成ivar。
由此,我认为一般规则是,如果您没有@synthesize,并且没有完全实现该属性所需的所有方法,那么假设它是动态的,并且不会生成ivar。
无论如何,如果您希望确保不生成IVAR,那么将其声明为@dynamic。
关于@dynamic的澄清
从Objective-C编程语言中声明的属性:
You use the @dynamic keyword to tell the compiler that you will fulfill the API contract implied by a property either by providing method implementations directly or at runtime using other mechanisms such as dynamic loading of code or dynamic method resolution.
对我来说,即使直接实现getter和setter,也可以将属性标记为@dynamic。
- +1,尽管很少需要动态。
- 根据这里的各种评论stackoverflow.com/questions/1160498/…使用@dynamic是错误的,因为我提供了getter和setter。
- @znq i更新了我的帖子,提供了更多关于动态的信息。
- 好吧,这似乎是正确的!听到这么简单真是太好了!
- 如果实现所有必需的访问器方法(只读属性的getter,读写属性的getter+setter),则不会自动合成属性。--stackoverflow.com/a/16772676/456536
- @是的,我得出了同样的结论:如果您没有@synthesis,并且没有完全实现该属性所需的所有方法,那么就假定它是动态的,不会生成ivar。没有来自苹果、LLVM或Clang的文件说明这一事实。所以,我展示了我的工作。你链接到的答案没有提供来源,但是声明它是事实,没有任何解释。那不是我的风格。
- @杰弗里托马斯干得好,保持你的风格。但我认为这将是一个更好的答案--"如果您没有@synthesis,并且没有完全实现该属性所需的所有方法,那么就假定它是动态的,不会生成ivar。苹果、LLVM或Clang没有任何文件说明这一事实。
如果将属性标记为只读并自己实现getter,则似乎不会创建ivar。
接口声明:
1
| @property (nonatomic, readonly) BOOL myBoolProp; |
强制执行:
1 2 3
| - (BOOL)myBoolProp {
return true;
} |
尝试这个:
1 2 3 4
| - (void)viewDidLoad {
[super viewDidLoad];
_myBoolProp = true;
} |
将生成错误:使用未声明的标识符"_myboolprop"
删除自定义getter方法也会删除错误,这似乎表明已经生成了ivar。
- 仅仅因为你不能用你期望的名字引用ivar,并不意味着它不在那里。我强烈建议使用运行时来确保没有实际生成任何IVAR。
- 在WWDC 2012演示文稿"现代目标C"中,它指出对于只读属性,"如果让我们合成getter,您将得到一个实例变量,否则您将不会"
是的-ivar仍然由clang生成(不是xcode,因为它是ide,clang是真正重要的编译器)。
如果您真的不想要ivars,也不想要实现,那么有一个有点陈旧的@dynamic关键字可以满足您的需要,或者您可以在协议中指定属性,这不会使其自动合成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| // .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。)
- @这不是指杰弗里所说的边缘案件。这是指行动计划中概述的单一情况。因此,在大多数情况下,他所说的是正确的。
- 根据这里的各种评论stackoverflow.com/questions/1160498/&hellip;使用@dynamic是错误的,因为我提供了getter和setter。
- @znq它不是"错误的"。最初的用例是这样的,是的,但是语言已经进化了,如果您不希望ivars到处飞行,那么@dynamic会变得更有趣。