继承属性,当readwrite在readonly的继承属性中时setter不合成 [英] Inheriting properties, setter not synthetized when readwrite in inherited property from readonly

查看:198
本文介绍了继承属性,当readwrite在readonly的继承属性中时setter不合成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用属性时,我发现了一个奇怪的行为,它被继承为只读,而在继承类中被重写为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆