抽象:
这个问题是关于属性的继承,以及从继承属性的类的内部和外部的不同读/写访问。
详情:
我有一个班级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
为什么会出现此警告,我应该如何构建代码以避免它?
答案 0 :(得分:10)
您需要在拥有的类(A
)上将该属性声明为读写,然后在子类(B
)上重新声明,以使编译器知道您要在那里使用它。因此,A
托管访问者方法,B
使用它。通常,您不希望B
创建另一个访问器方法,因此您可以使用@dynamic
告诉编译器超类(技术上,只是另一个类)将提供实现。
请注意,您还可以在A
。B
上声明一个类别(不是扩展名),其中明确声明了存取方法(不使用属性,只是方法),因为这是什么您实际上对此感兴趣(您实际上并不想要属性指定的任何其他内容,并且您并不真正想要确保属性属性在超类和子类中匹配的维护开销)...