类似实例变量的扩展 [英] Category-like extension for instance variables

查看:121
本文介绍了类似实例变量的扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法以某种方式模拟类的行为,因为类的实例变量而不是方法?

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 IBOutlets. 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 extends ClassA (类别方式);

  • ClassB 继承 ClassA ClassB 可以调用 ClassA 方法);

  • ClassB 可以通过 ClassA 名称(类别方式)访问

  • ClassB "extends" ClassA (category way);
  • ClassB inherits ClassA (ClassB can call ClassA methods);
  • ClassB can be accessed through ClassA name (category way)

这篇关于类似实例变量的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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