我知道现代的Objective-C运行时可以合成ivars.我认为合成的ivars的行为与标记的ivars完全相同@private,但它们没有.
因此,代码仅在我预期可以处理的现代运行时下进行编译.例如,一个超类:
@interface A : NSObject {
#if !__OBJC2__
@private
NSString *_c;
#endif
}
@property (nonatomic, copy) NSString *d;
@end
@implementation A
@synthesize d=_c;
- (void)dealloc {
[_c release];
[super dealloc];
}
@end
Run Code Online (Sandbox Code Playgroud)
和子类:
@interface B : A {
#if !__OBJC2__
@private
NSString *_c;
#endif
}
@property (nonatomic, copy) NSString *e;
@end
@implementation B
@synthesize e=_c;
- (void)dealloc {
[_c release];
[super dealloc];
}
@end
Run Code Online (Sandbox Code Playgroud)
即使超类的ivar是私有的,子类也不能具有与其超类的声明的ivar同名的声明的ivar.这似乎违反了我的意思@private,因为子类受到超类选择私有的影响.
然而,我更关心的是我应该如何看待合成的伊娃.我认为他们的行为就像宣布的私人伊娃,但没有脆弱的基类问题.也许这是正确的,我只是不明白脆弱的基类问题.为什么上面的代码只在现代运行时编译?当所有超类实例变量都是私有的时,是否存在脆弱的基类问题?
合成的伊娃是私人的.你所看到的是编译器正常工作.
忽略!__OBJ2__条件内的代码.我只会看一下合成的ivars案例.
这就是您的代码所具有的:
A::_c是一种合成的ivar,只能在实施过程中访问A.B::_c是一种合成的ivar,只能在实施过程中访问B.它们不是同一个变量.它们不会发生冲突,也不会存储相同的值.
仍然可能出现问题的情况......
如果您尝试将Aand和B实现放在同一个文件中,编译器现在可以A::_c在编译B时查看声明,并阻止您_c在该@synthesize e=_c;行中访问B.
它为什么要这样做?我不是只是这么说A::_c而且B::_c是不相关的变量吗?
将两个实现放在同一个文件中会产生一种情况,_c即编译器到达时不是未声明的标识符@synthesize e=_c;,因此编译器不会尝试创建新的合成ivar B,而是尝试访问A::_c并失败(因为它A::_c是私有的).
| 归档时间: |
|
| 查看次数: |
2089 次 |
| 最近记录: |