【问题标题】:Under what conditions is @synthesize automatic in Objective-c?Objective-c 在什么情况下@synthesize 是自动的?
【发布时间】:2012-03-11 05:44:15
【问题描述】:

Objective-c中@synthesize在什么情况下是自动的?

也许在使用 LLVM 3.0 及更高版本时?从网上阅读看来,从 Xcode 4 开始,@synthesize 似乎是不必要的。但是我正在使用 Xcode 4 并在我没有 @synthesize 属性时收到警告。

Why don't properties get automatically synthesized 的某些回复似乎暗示@synthesize 在某些情况下可以在某些时候省略。

Another (old) reference 暗示 @synthesize 可能在未来的某个时候自动出现。

【问题讨论】:

  • 你有链接说明@synthesize 被描述为不必要的地方吗?
  • 也许他看到了一些关于当前处于 NDA 下的 Xcode 4.4 的信息,并且对版本号感到困惑。
  • @bneely 添加了链接。也许我误读了“@synthesize 在最新版本的 LLVM 2.0 编译器中是自动的”。
  • @robmayoff 更像是我一直在阅读可能过时的信息 :-) 请参阅上面的链接。

标签: objective-c llvm synthesize


【解决方案1】:

从 clang 3.2(大约 2012 年 2 月)开始,默认提供 Objective-C 属性的“默认合成”(或“自动属性合成”)。它基本上与您最初阅读的博客文章中的描述相同:http://www.mcubedsw.com/blog/index.php/site/comments/new_objective-c_features/(除了该文章将该功能描述为“启用,然后禁用”;我不知道这是否是 Xcode 的问题,或者 clang 开发人员本身是否已经离开来回讨论这个问题)。

据我所知,在clang 3.2 中不会默认合成属性的唯一情况是这些属性是从协议继承的。这是一个例子:

#import <Foundation/Foundation.h>

@protocol P
@property int finicky;
@end

@interface A : NSObject <P>
@property int easygoing;
@end

@implementation A
@end

int main() { A *a = [A new]; a.easygoing = 0; a.finicky = 1; }

如果你编译这个例子,你会得到一个警告:

test.m:11:17: warning: auto property synthesis will not synthesize property
      declared in a protocol [-Wobjc-protocol-property-synthesis]
@implementation A
                ^
test.m:4:15: note: property declared here
@property int finicky;
              ^
1 warning generated.

如果你运行它,你会从运行时得到一个错误:

objc[45820]: A: Does not recognize selector forward:: (while forwarding setFinicky:)
Illegal instruction: 4

【讨论】:

    【解决方案2】:

    从 Xcode 4.4 开始,如果您不为属性编写 @synthesize@dynamic。编译器的行为就像你写了@synthesize property = _property

    在 Xcode 4.4 之前,您必须为每个属性执行以下操作之一,否则编译器将发出警告,您将收到运行时错误。在 Xcode 4.4 或更高版本中,您可以执行以下任何操作,而不是让编译器自动合成属性访问器和实例变量。

    1. 使用@synthesize 指令。
    2. 使用@dynamic 指令并以某种方式在运行时提供属性getter 和(如有必要)setter。
    3. 显式编写属性getter方法,如果属性为readwrite,则使用属性setter方法。

    请注意,您可以使用@synthesize 指令(或@dynamic 指令)并且显式提供getter 和/或setter 方法。但是如果你省略它们,@synthesize 会提供它们。

    【讨论】:

    • 如果你同时提供 getter 和 setter,那么你就失去了自动 ivar,对吧?
    【解决方案3】:

    来自New Features in Xcode 4.4 文档:

    Objective-C @properties 在未显式实现时默认合成。

    所以@synthesize 从 Xcode 4.4 和 LLVM 4.0 编译器开始默认是自动的。

    【讨论】:

    • 请注意,32 位 Mac OS X 不支持自动合成。
    【解决方案4】:

    此外,如果您手动实现了 setter 和 getter,则合成不会自动进行。因此,如果您想知道为什么在声明 @property (...) SomeType someVariable 后无法访问 _someVariable,那是因为您已经实现了 setSomeVariable: 和 someVariable 方法。

    【讨论】:

      【解决方案5】:

      您可以通过单击左侧 Project Navigator 中的项目名称然后单击 Build Settings 中的 All Cobined 然后搜索 synthesize 来关闭合成警告。那应该设置为否。

      【讨论】:

      • 其实这是唯一正确的答案,一个旧的答案。其余的深入。如果您有多个目标,请务必检查所有目标的设置
      猜你喜欢
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多