属性继承:自动属性合成不会合成属性

时间:2014-07-04 09:05:01

标签: objective-c inheritance properties

抽象

这个问题是关于属性的继承,以及从继承属性的类的内部和外部的不同读/写访问。

详情

我有一个班级A和另一个班级B,它继承自A。在someProperty中声明了属性A。我希望该属性只能从这些类外部读取,并从内部读/写。

只有一个类,这很简单:您只需将.h中的属性声明为readonly,然后在类别的.m内再次将其声明为readwrite。完成。

但是有两个类,一个派生自另一个,我在B得到了以下编译器警告:

  

自动属性合成不会合成属性&some;属性'   因为它是'readwrite'但它将被合成' readonly'通过   另一个属性

以下是代码:

A.H:

#import <Foundation/Foundation.h>

@interface A : NSObject

// This property shall be readonly from outside, but read/write from subclasses
@property (readonly) SInt32 someProperty;

@end

A.M:

#import "A.h"

@implementation A
@end

B.h:

#import <Foundation/Foundation.h>
#import "A.h"

@interface B : A

@end

B.m:

#import "B.h"    

@interface B ()

// compiler warning in the following property declaration:
// /Users/.../B.m:12:41: Auto property synthesis will not synthesize property
// 'someProperty' because it is 'readwrite' but it will be synthesized
// 'readonly' via another property
@property (readwrite) SInt32 someProperty;

@end

@implementation B
@end

为什么会出现此警告,我应该如何构建代码以避免它?

1 个答案:

答案 0 :(得分:10)

您需要在拥有的类(A)上将该属性声明为读写,然后在子类(B)上重新声明,以使编译器知道您要在那里使用它。因此,A托管访问者方法,B使用它。通常,您不希望B创建另一个访问器方法,因此您可以使用@dynamic告诉编译器超类(技术上,只是另一个类)将提供实现。

请注意,您还可以在AB上声明一个类别(不是扩展名),其中明确声明了存取方法(不使用属性,只是方法),因为这是什么您实际上对此感兴趣(您实际上并不想要属性指定的任何其他内容,并且您并不真正想要确保属性属性在超类和子类中匹配的维护开销)...