据我所知,从 XCode 4.4 开始@synthesize
将自动生成属性访问器。但刚才我读了一个关于的代码示例NSUndoManager
,并且在代码中它注意到@synthesize
被明确添加。喜欢:
@interface RootViewController ()
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@property (nonatomic, strong) NSUndoManager *undoManager;
@end
@implementation RootViewController
//Must explicitly synthesize this
@synthesize undoManager;
我现在很困惑......我应该什么时候添加@synthesize
明确地写到我的代码?
答案有很多,但也有很大的困惑。我会尝试下一些订单(或增加混乱,我们会看到......)
让我们停止谈论 Xcode。 Xcode 是一个IDE。铿锵是一个compiler。我们正在讨论的这个功能称为属性的自动合成这是一个clang 支持的 Objective-C 语言扩展 http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-autosynthesis-of-properties,这是 Xcode 使用的默认编译器。
需要明确的是,如果您在 Xcode 中切换到 gcc,您将不会从该功能中受益(无论 Xcode 版本如何)。同样,如果您使用文本编辑器并从命令行使用 clang 进行编译,您将无法从该功能中受益。将要。
-
感谢自动合成,您不需要显式地合成该属性,因为它将由编译器自动合成为
@synthesize propertyName = _propertyName
但是,也存在一些例外情况:
-
具有自定义 getter 和 setter 的读写属性
当提供bothgetter 和 setter 自定义实现,属性不会自动合成
-
具有自定义 getter 的只读属性
为只读属性提供自定义 getter 实现时,不会自动合成
-
@dynamic
使用时@dynamic propertyName
,该属性不会自动合成(非常明显,因为@dynamic
and @synthesize
是互斥的)
-
@protocol 中声明的属性
当遵守协议时,协议定义的任何属性都不会被自动合成
-
在类别中声明的属性
在这种情况下,@synthesize
编译器不会自动插入指令,但也无法手动合成该属性。虽然类别可以声明属性,但它们根本无法合成,因为类别无法创建 ivar。为了完整起见,我会补充一点,这仍然是可能的使用 Objective-C 运行时伪造属性合成 https://stackoverflow.com/questions/8733104/objective-c-property-in-category.
-
覆盖的属性(自 clang-600.0.51 起新增,随 Xcode 6 一起发布,感谢 Marc Schlüpmann)
当您覆盖超类的属性时,您必须显式合成它
值得注意的是,合成属性会自动合成后备 ivar,因此如果缺少属性合成,ivar 也会丢失,除非明确声明。
除了最后三种情况之外,一般的理念是,每当您手动指定有关属性的所有信息时(通过实现所有访问器方法或使用@dynamic
)编译器会假设您想要完全控制该属性,并将禁用其自动合成。
除了上面列出的情况外,唯一使用显式@synthesize
将指定一个不同的 ivar 名称。然而约定很重要,所以我的建议是始终使用默认命名。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)