我可以为类类型变量指定特定的超类要求吗?

时间:2010-08-22 22:37:06

标签: iphone objective-c dynamic-typing

我正在创建一个初始化某些类的实例的类。该类将用于初始化几个不同类型的类,这些类都是从一个公共超类中继承而来的。目前我正在使用实例变量:

Class templateClass;

存储类类型。我收到编译器警告说templateClass不支持方法。有没有办法来抑制这些警告或指定模板类必须是某个类的子类? 另外,这是在objective-c中实现此目的的理想方式吗?有没有不同的方法来指定我应该使用的类?
谢谢你的帮助!

编辑: 我写的课程是为了在随机选择的位置创建精灵,并使用一些变量来限制它们。这个类要求它所引用的类具有initWithX:(int)pos yVariance:(int)variance方法。我希望可以使用你提到的protocals来定义。我将为我必须创建的每种类型的精灵制作rezzing类的多个实例。我希望能够发送rezzing类initWithTemplateClass:(Class)templateClass来定义要创建的精灵类型。我不确定这是否是正确的方法,因为编译器发布方法initWithX:(int)pos yVariance:(int)variance不可用于templateClass。我希望我的方式存在问题。 显示警告的代码是:

[self addChild:[[templateClass alloc] initWithX:positionOfChild  
  yVariance:(random()%(rowVarianceSize+1))]];

2 个答案:

答案 0 :(得分:4)

您可以使用所有必需的方法定义protocol。然后声明你的类符合该协议。

答案 1 :(得分:1)

编辑添加第二个替代

当我编译一个试图做你正在做的事情的简单测试用例时,我没有得到那个警告(我也没想到)。

那就是说,你所做的似乎是完全合理的。虽然'addChild'示例中确实存在泄漏。你分配/初始化你的新对象,保留计数为1,然后(假设'self'是UIView)你对addChild的调用也将保留对象,但你没有自己的引用来释放。

id obj = [[templateClass alloc] initWithX:positionOfChild yVariance:(random()%(rowVarianceSize+1))]];
[self addChild:obj];
[obj release], obj = nil;

此外,弗拉基米尔建议定义协议是一个很好的建议,如果你这样做,你甚至可以插入一个运行时检查,你给出的templateClass符合该协议。

if ([templateClass conformsToProtocol:@protocol(Foo)]) {
    id<Foo> obj = [[templateClass alloc] initWithX:positionOfChild yVariance:(random()%(rowVarianceSize+1))]];
    [self addChild:obj];
    [obj release], obj = nil;
} else {
    // Do whatever you want to do if templateClass isn't correct.
    // Obviously you could also have the protocol conformance check elsewhere.
}

但是,作为所有这些的替代,您可以为工厂对象定义一个接口,而不是使用您的Class实例变量,该接口可以创建您想要的特定类型的精灵。然后传入适当的工厂类实例。

例如:

@interface Sprite : UIView {
}
- (id)initWithX:(int)pos yVariance:(int)variance;
@end

@interface SpriteFactory {
}
- (Sprite*)createSprite;
@end

然后创建子类对:Sprite子类和创建这种精灵的SpriteFactory子类。

然后,您将使用“SpriteFactory * factory”而不是使用“Class templateClass”。