本文介绍了什么时候应该显式使用@synthesize?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,自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?

解决方案

答案很多,但也很混乱.我会尝试下订单(或增加混乱,我们将看到...)

  1. 让我们停止谈论Xcode. Xcode是 IDE . clang是编译器.我们正在讨论的此功能称为属性自动合成,它是 clang 支持的目标C语言扩展,这是Xcode使用的默认编译器.
    为了清楚起见,如果您在Xcode中切换到gcc,则不会从此功能中受益(无论从Xcode版本开始).以同样的方式,如果您使用文本编辑器并在命令行中使用clang进行编译,则您会.

  2. 由于自动合成,您无需显式合成属性,因为它将由编译器自动合成为

    @synthesize propertyName = _propertyName
    

    但是,有一些例外情况:

    • 具有自定义getter和setter的readwrite属性

      在同时提供的getter和setter自定义实现时,该属性将不会自动合成

    • 具有自定义getter的只读属性

      在为readonly属性提供自定义getter实现时,不会自动合成

    • @dynamic

      使用@dynamic propertyName时,该属性不会自动合成(很明显,因为@dynamic@synthesize是互斥的)

    • 在@protocol中声明的
    • 属性

      遵守协议时,协议定义的任何属性都不会自动合成

    • 在类别中声明的属性

      在这种情况下,编译器不会自动插入@synthesize指令,但是也无法手动合成此属性.尽管类别可以声明属性,但由于类别无法创建Ivar,因此根本无法进行合成.为了完整起见,我将添加使用Objective伪造属性合成的可能性-C运行时.

    • 覆盖的属性(自clang-600.0.51起新增,随Xcode 6一起提供,谢谢MarcSchlüpmann)

      当您覆盖超类的属性时,必须显式地对其进行合成

值得注意的是,合成属性会自动合成支持的ivar,因此,如果缺少属性综合,除非明确声明,否则ivar也将丢失.

除了后三种情况外,一般的思想是,每当您手动指定有关属性的所有信息(通过实现所有访问器方法或使用@dynamic)时,编译器都会假定您希望完全控制该属性,并且它将禁用自动合成功能.

除了上面列出的情况外,显式@synthesize的唯一其他用途是指定不同的ivar名称.但是约定很重要,因此我的建议是始终使用默认命名.

As far as I know, since XCode 4.4 the @synthesize will auto-generate the property accessors. But just now I have read a sample of code about NSUndoManager, and in the code it noticed that the @synthesize is added explicitly. Like:

@interface RootViewController  ()

@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@property (nonatomic, strong) NSUndoManager *undoManager;

@end

@implementation RootViewController
//Must explicitly synthesize this
@synthesize undoManager;

I am feeling puzzled now... When should I add @synthesize explicitly to my code?

解决方案

There's a lot of answers, but also a big confusion. I'll try to put some order (or increase the mess, we'll see...)

  1. Let's stop talking about Xcode. Xcode is an IDE. clang is a compiler. This feature we are discussing is called autosynthesis of properties and it's an Objective-C language extension supported by clang, which is the default compiler used by Xcode.
    Just to make it clear, if you switch to gcc in Xcode, you won't benefit from this feature (regardless from the Xcode version.) In the same way if you use a text editor and compile using clang from the command line, you will.

  2. Thank to autosynthesis you don't need to explicitly synthesize the property as it will be automatically synthesized by the compiler as

    @synthesize propertyName = _propertyName
    

    However, a few exceptions exist:

    • readwrite property with custom getter and setter

      when providing both a getter and setter custom implementation, the property won't be automatically synthesized

    • readonly property with custom getter

      when providing a custom getter implementation for a readonly property, this won't be automatically synthesized

    • @dynamic

      when using @dynamic propertyName, the property won't be automatically synthesized (pretty obvious, since @dynamic and @synthesize are mutually exclusive)

    • properties declared in a @protocol

      when conforming to a protocol, any property the protocol defines won't be automatically synthesized

    • properties declared in a category

      this is a case in which the @synthesize directive is not automatically inserted by the compiler, but this properties cannot be manually synthesized either. While categories can declare properties, they cannot be synthesized at all, since categories cannot create ivars. For the sake of completeness, I'll add that's it's still possible to fake the property synthesis using the Objective-C runtime.

    • overridden properties (new since clang-600.0.51, shipping with Xcode 6, thanks Marc Schlüpmann)

      when you override a property of a superclass, you must explicitly synthesize it

It's worth noting that synthesizing a property automatically synthesize the backing ivar, so if the property synthesis is missing, the ivar will be missing too, unless explicitly declared.

Except for the last three cases, the general philosophy is that whenever you manually specify all the information about a property (by implementing all the accessor methods or using @dynamic) the compiler will assume you want full control over the property and it will disable the autosynthesis on it.

Apart from the cases that are listed above, the only other use of an explicit @synthesize would be to specify a different ivar name. However conventions are important, so my advice is to always use the default naming.

这篇关于什么时候应该显式使用@synthesize?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-11 02:55