自升级到Xcode 5.1以来,我开始在我的项目使用的某些代码中看到以下警告。我想弄明白它意味着什么。
警告:Auto property synthesis will not synthesize property 'responseHeader' because it is 'readwrite' but it will be synthesized 'readonly' via another property
.m文件中出现的代码:
@interface S3Response ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end
以前的属性声明,在.h文件中:
@property (nonatomic, readonly) NSDictionary *responseHeader;
该属性没有@synthesize
语句,responseHeader
或setResponseHeader
也没有被定义为方法。然而,有一个名为responseHeader
的ivar的明确定义。
对我来说似乎很简单:对于类的用户,属性被声明为只读,但是本地读写,因此类可以设置它。
这个警告意味着什么,我应该怎么做呢?
答案 0 :(得分:24)
该代码似乎来自AWS SDK for iOS,
S3Response
是AmazonServiceResponse
的子类。
public AmazonServiceResponse
接口定义了一个只读属性
@interface AmazonServiceResponse:NSObject
// ...
@property (nonatomic, readonly) NSDictionary *responseHeader;
@end
在实现文件的类扩展中重新定义为读写:
@interface AmazonServiceResponse ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end
现在子类 S3Response
也希望对此属性进行读写访问,
因此也在其实现文件的类扩展中定义:
@interface S3Response ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end
编译器抱怨因为 - 编译" S3Response.m" - 它不知道 该属性的 setter 存在于超类中(它不读取 此时超类的实现文件)。编译器也不能 简单地在子类中合成一个setter,因为它不能不知道 属性由超类中的实例变量备份。
但你知道会生成一个setter,所以你可以删除警告
在子类实现中添加@dynamic
声明:
@implementation S3Response
@dynamic responseHeader;
...
@dynamic
是"承诺"编译器所有必需的访问器方法
在运行时可用。
答案 1 :(得分:-1)
这里的问题如下。
默认情况下,如果不明确写入所有权(weak / retain / strong / assign),xCode将自动检查类型。因此,对于NSDictionary,它将 strong 。因此,在界面中你将有
@property (nonatomic, readonly, strong) NSDictionary *responseHeader;
那么它将与你的私有实现定义相矛盾
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
Compilator与强大不匹配并保留在属性合成下虽然它是正式相同的东西。
为了解决问题,您可以在两种情况下编写保留,或者更正确,您根本不应该写保留。默认情况下,两种定义都会很强。