继承属性,当readwrite在readonly的继承属性中时setter不合成 [英] Inheriting properties, setter not synthetized when readwrite in inherited property from readonly
问题描述
在使用属性时,我发现了一个奇怪的行为,它被继承为只读,而在继承类中被重写为readwrite
strong>
@interface A:NSObject
@property(nonatomic,strong,readonly)一些属性
@end
在 Bh p>
@interface B:A
//无论如果这里
// @property非原子,强,读写)NSObject * someProperty;
- (void)foo;
@end
在 Bm p>
@interface B()
//无论如何
@property强,读写)NSObject * someProperty;
@end
@implementation B
- (void)foo {
NSLog(@%@ ,self.someProperty);
//使用无法识别的选择器崩溃此处setSomeProperty:
self.someProperty = [NSObject new];
}
@end
呼叫
self.someProperty = [NSObject new]; p>
调查显示,即使在声明为readwrite时,setter似乎没有合成
为什么会发生这种情况?编译器没有指示任何警告这种情况发生,也没有我发现这个行为记录任何地方
解决方案您的官方参考,但这是我经历的:对于从超类继承的属性,编译器不生成任何访问器方法。
在你的情况下,属性在类A中被声明为 readonly
,这样编译器创建
只有一个getter方法。类B中的重新声明不创建任何附加的访问器
方法。原因可能是B类不知道在A类中如何实现属性(它不需要是一个实例变量)。
所以属性声明子类只是一个promise给编译器
getter和setter函数将在运行时可用(类似于@dynamic声明)。
如果没有setter,那么你将得到一个运行时异常。
所以在子类中重新声明属性的一个用例是,如果超类
在 接口中将属性声明为只读,但在
( private )类扩展中为读写:
// Ah
@interface A:NSObject
@property(nonatomic,strong,readonly)NSObject * someProperty;
@end
// A.m
@interface A()
@property(nonatomic,strong,readwrite)NSObject * someProperty;
@end
@implementation A
@end
在这种情况下,setter和getter都在类A中创建,类B
可以在其实现中将属性重新声明为读写。
I discovered a strange behaviour when working with a property, that was inherited as readonly and than redeclared in the inherited class as readwrite
In A.h
@interface A : NSObject
@property (nonatomic, strong, readonly) NSObject * someProperty;
@end
In B.h
@interface B : A
// no matter if here
// @property (nonatomic, strong, readwrite) NSObject * someProperty;
- (void)foo;
@end
In B.m
@interface B()
// no matter if here
@property (nonatomic, strong, readwrite) NSObject * someProperty;
@end
@implementation B
- (void)foo {
NSLog(@"%@", self.someProperty);
// crash here with unrecognized selector setSomeProperty:
self.someProperty = [NSObject new];
}
@end
calling
self.someProperty = [NSObject new];
causes the code to crash on unrecognized selector "setSomeProperty:"
investigation showed, that it looks like the setter did not get synthetized, even when declared as readwrite
Why is this happening? The compiler didnt indicate any warning for this to happen, nor i found anywhere this behaviour documented
解决方案 I cannot give you an official reference, but this is what I experienced: For a property inherited from a superclass, the compiler does not generate any accessor methods.
In your case, the property is declared as readonly
in class A, so that the compiler creates
only a getter method. The re-declaration in class B does not create any additional accessor
methods. The reason might be that class B does not know "how" the property is realised in class A (it need not be an instance variable).
So the property declaration in the subclass is only a "promise" to the compiler that
getter and setter functions will be available at runtime (similar to a @dynamic declaration).
If there is no setter then you will get a runtime exception.
So a use case of re-declaring the property in the subclass would be if the superclass
declares the property as read-only in the public interface, but as read-write in the
(private) class extension:
// A.h
@interface A : NSObject
@property (nonatomic, strong, readonly) NSObject * someProperty;
@end
// A.m
@interface A()
@property (nonatomic, strong, readwrite) NSObject * someProperty;
@end
@implementation A
@end
In this case, both setter and getter are created in the class A, and class B
can re-declare the property as read-write in its implementation.
这篇关于继承属性,当readwrite在readonly的继承属性中时setter不合成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!