有一个看起来像这样的类(为简洁起见,我省略了导入):
基数.h:
@interface Base : NSObject
@property (strong, readonly) NSString *something;
- (id)initWithSomething:(NSString *)something;
@end
基数:
@implementation Base
- (id)initWithSomething:(NSString *)something {
self = [super init];
if (self) _something = something;
return self;
}
@end
如您所见,'something' 属性是只读的。现在我想创建一个覆盖该属性的子类也可写:
子.h:
@interface Sub : Base
@property (strong) NSString *something;
@end
分米:
@implementation Sub
@end
和代码:
主.c:
int main(int argc, const char * argv[]) {
@autoreleasepool {
Sub *o = [Sub new];
o.something = @"foo";
NSLog(@"%@", o.something);
}
return 0;
}
此代码导致:
2013-09-07 13:58:36.970 ClilTest[3094:303] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[Sub setSomething:]: unrecognized
selector sent to instance 0x100109ff0'
这是为什么?为什么找不到 setSelector?
当我在子类中执行此操作时:
分米:
@implementation Sub
@synthesize something = _something;
@end
一切正常。这是否意味着子类的属性默认情况下不会合成,即使它@property
在@interface
? 编译是否以某种方式“看到”从 Base 自动生成的 getter 并且不生成 setter?为什么,我认为应该生成setter,因为它还不存在。我正在使用 Xcode 4.6.2 并且该项目是一个 Cli 工具(类型 Foundation),但在我的实际项目中也是如此,它是一个 iPhone 应用程序。
背景:我有一个需要蓝牙连接到某些设备的重型对象(Base 的实例),我应该为某些功能创建一个视图控制器。为了便于测试,我不想连接到 BT(实际上,我需要一个物理设备并测试其上的代码),我希望能够在模拟器中对其进行测试。我想出的是,我只是创建一个子类(Sub),它存根一些方法/属性并使用它,当代码准备好时,我只需删除子类的代码,用正确的实例替换它的实例,使用设备进行测试,提交并推送。它实际上工作正常,除了@property
上面的奇怪东西。
有人可以告诉我财产覆盖发生了什么吗?