xcode 这个objective-c属性综合警告是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22443593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:46:44  来源:igfitidea点击:

What does this objective-c property synthesis warning mean?

objective-cxcode

提问by dpassage

Since upgrading to Xcode 5.1, I'm starting to see the following warning in some code my project uses. I'm trying to figure out what it means.

自从升级到 Xcode 5.1 后,我开始在我的项目使用的某些代码中看到以下警告。我试图弄清楚这意味着什么。

Warning: Auto property synthesis will not synthesize property 'responseHeader' because it is 'readwrite' but it will be synthesized 'readonly' via another property

警告: Auto property synthesis will not synthesize property 'responseHeader' because it is 'readwrite' but it will be synthesized 'readonly' via another property

The code where it's occurring, in the .m file:

它发生的代码,在 .m 文件中:

@interface S3Response ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end

The previous declaration of the property, in the .h file:

.h 文件中属性的先前声明:

@property (nonatomic, readonly) NSDictionary *responseHeader;

There is no @synthesizestatement for that property, nor are responseHeaderor setResponseHeaderdefined as methods. There is however an explicit definition of an ivar named responseHeader.

没有@synthesize对该属性的声明,也没有responseHeadersetResponseHeader定义为方法。然而,有一个名为 的 ivar 的明确定义responseHeader

Seems pretty straightforward to me: property is declared as read-only for users of the class, but read-write locally so the class can set it.

对我来说似乎很简单:属性被声明为类的用户只读,但在本地读写,以便类可以设置它。

What does this warning mean, and what should I do about it?

这个警告是什么意思,我应该怎么做?

回答by Martin R

That code seems to be from the AWS SDK for iOS, and S3Responseis a subclass of AmazonServiceResponse.

该代码似乎来自适用于 iOSAWS 开发工具包,并且S3ResponseAmazonServiceResponse.

The public AmazonServiceResponseinterface defines a read-only property

公共AmazonServiceResponse接口定义了一个只读属性

@interface AmazonServiceResponse:NSObject
// ...
@property (nonatomic, readonly) NSDictionary *responseHeader;
@end

which is redefined as read-write in a class extension in the implementation file:

在实现文件的类扩展中重新定义为读写:

@interface AmazonServiceResponse ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end

Now the subclassS3Responsealso wants read-write access to this property, and therefore also defines in the class extension of its implementation file:

现在子类S3Response也想要对这个属性进行读写访问,因此也在其实现文件的类扩展中定义:

@interface S3Response ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end

The compiler complains because – when compiling "S3Response.m" – it does not know that a setterfor the property exists in the superclass (it does not read the implementation fileof the superclass at that point). Also the compiler cannot simply synthesize a setter in the subclass, because it cannot not know that the property is backed-up by an instance variable in the superclass.

编译器抱怨是因为——在编译“S3Response.m”时——它不知道超类中存在属性的设置器(此时它不读取超类的实现文件)。此外,编译器不能简单地在子类中合成一个 setter,因为它无法知道该属性由超类中的实例变量支持。

But you knowthat a setter will be generated, so you can remove the warning by adding a @dynamicdeclaration to the subclass implementation:

但是您知道将生成一个 setter,因此您可以通过向@dynamic子类实现添加声明来消除警告:

@implementation S3Response
@dynamic responseHeader;
...

@dynamicis a "promise" to the compiler that all necessary accessor methods will be available at runtime.

@dynamic是对编译器的“承诺”,即所有必需的访问器方法都将在运行时可用。

回答by malex

The problem here is as follows.

这里的问题如下。

By default, if don't write ownership (weak/retain/strong/assign) explicitly, xCode will check the type automatically. So in case of NSDictionary it will be strong. Thus, in interface you will have

默认情况下,如果不明确写入所有权(弱/保留/强/分配),xCode 将自动检查类型。所以在 NSDictionary 的情况下,它会很强大。因此,在界面中,您将拥有

@property (nonatomic, readonly, strong) NSDictionary *responseHeader;

Then it will be contradict you private implementation definition

那么它将与您的私有实现定义相矛盾

@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;

Compilator doesn't match strong and retain under property synthesizing though it is formally the same thing.

虽然编译器在形式上是一回事,但编译器并不匹配strong和retaining属性综合。

To cure situation you can write retainin both cases, or more correct, you should not write retain at all. It will be strong by default in both definitions.

为了解决这种情况,您可以在两种情况下都编写保留,或者更正确的是,您根本不应该编写保留。默认情况下,它在两个定义中都是强大的。