类似实例变量的扩展 [英] Category-like extension for instance variables
问题描述
有没有办法以某种方式模拟类的行为,因为类的实例变量而不是方法?
Is there a way to somehow emulate category behavior for a class regarding to it's instance variables, not methods ?
我有一个 ClassA
,我希望在使用新方法扩展它后保留其名称,并从其他cllass( ClassB
)扩展ivars。
当然,我可以继承 ClassA
,但结果类会有不同的名称。
I have a ClassA
, and I want to keep its name after extending it with new methods AND ivars from other cllass (ClassB
).
Of course, I can inherit ClassA
, but resulting class will have different name.
对于方法此外,这不是问题 - 类别将是一个很好的解决方案。
For methods addition, it's not a problem - category would be a good solution.
更新: ClassA
用作XIB的文件所有者,这些要扩展的字段是 IBOutlet
s。所以我在构建阶段需要它们。
UPDATE: ClassA
used as file owner for a XIB, and these fields to be extended are IBOutlet
s. So I need them at build phase.
推荐答案
我调查了这个问题,围绕 关联参考 (感谢 Ole ),方法静态变量,方法调整,最后来这个简单的解决方案(没有运行时的东西)。我只是使用分类类来返回指向派生类的指针,当然这可以包含额外的ivars。这样做我实现了一个意想不到的好处:我可以调用 super
的类方法,这在扩展类别时是不可能的。
I've investigated this question playing around associative references (thanks to Ole), with methods static variables, methods swizzling, and finally come to this simple solution (no runtime stuff). I simply use "categorized" class only to return a pointer to a derived class, which of course can contain additional ivars. Doing so I achieve one unexpected benefit: I can call super
's class methods, which is impossible when extending through categories.
类扩展示例(已测试):
ClassA + ClassB .h
ClassA+ClassB.h
@protocol _ClassB_Protocol
@optional // to avoid warnings
- (IBAction) onClick:(id)sender;
@property (nonatomic, retain) IBOutlet UIButton *aButton;
@end
@interface ClassA (_ClassA_Category) <_ClassB_Protocol>
@end
@interface ClassB: ClassA <_ClassB_Protocol> {
UIButton *aButton; // _ivar_ to add
}
@end
ClassA + ClassB.m
ClassA+ClassB.m
@implementation ClassA (_ClassA_Category)
// this will be called first on [ClassA alloc] or [ClassA allocWithZone:(NSZone *)zone]
+(id) alloc {
if ([self isEqual: [ClassA class]]) {
return [ClassB alloc];
} else {
return [super alloc];
}
}
@end
@implementation ClassB: ClassA
@synthesize aButton;
-(void) dealloc {
[aButton release];
[super dealloc]; // this is impossible for an ordinary category
}
- (void) onClick:(id)sender {
// some code here
}
@end
现在我们在同一时间:
-
ClassB
extendsClassA
(类别方式); -
ClassB
继承ClassA
(ClassB
可以调用ClassA
方法); -
ClassB
可以通过ClassA
名称(类别方式)访问
ClassB
"extends"ClassA
(category way);ClassB
inheritsClassA
(ClassB
can callClassA
methods);ClassB
can be accessed throughClassA
name (category way)
这篇关于类似实例变量的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!