初始化对象,如果条件
我想创建一个对象,但该类型取决于如果条件的结果:初始化对象,如果条件
if ([type isEqualToString:@"day"]) {
GraphDayView *graphv = [[GraphDayView alloc] initWithFrame:rect];
} else {
GraphMonthView *graphv = [[GraphMonthView alloc] initWithFrame:rect];
}
的问题是,graphv超出范围,所以我不能够在if语句后使用它。 所以,我试图将其声明为一个id:
id graphv;
if ([type isEqualToString:@"day"]) {
graphv = [[GraphDayView alloc] initWithFrame:rect];
} else {
graphv = [[GraphMonthView alloc] initWithFrame:rect];
}
但现在的问题是,该编译器不知道什么样的对象grapv的是。所以:
graphv.backgroundColor = [UIColor whiteColor];
提供了一个错误。任何人都知道如何解决这个问题?
如果他们共享相同的超类,那么使用它来代替id。否则,创建两个变量,并将它们设置为nil:
GraphDayView *gdv = nil;
GraphMonthView *gmv = nil;
然后测试后的if语句,看看哪一个被初始化。
使GraphDayView和GraphMonthView都是GraphCalendarView的子类。然后使您的backgroundColor
成为GraphCalendarView的一个属性。
(或者,如果你的两个类都已经实现backgroundColor
然后你回家免费的UI类的子类)。
声明你的变量为GraphCalendarView graphv;
,然后像以前一样继续进行。如果你需要使用一个属性/方法,这对你的两个派生类中的一个或另一个来说是独一无二的,那么就先投射到那个类。
Assumin都是UIView子类,那么你可以简单地定义对象作为/ UIView的实例。这将为backgroundColor做。正如Hot Licks所建议的,根据子类的其他方法,您可能想要在UIView和您的子类之间引入一个通用超类。 – 2012-03-17 14:16:18
谢谢,这工作,很好的解决方案!一个问题,但。我在这两个子类中都有一个名为'setMeasurements'的方法。我应该将其声明为抽象方法还是最好做什么? – joostevilghost 2012-03-17 14:17:31
要么使它们继承自从'UIView'继承的公共基类,例如'@interface GraphCalendarView:UIView'然后'@interface GraphMonthView:GraphCalendarView'和'@interface GraphDayView:GraphCalendarView'。或者如果他们没有真正分享任何其他的共同性,并且你不想强加这种关系,你可以创建一个他们都遵守的协议,他们可以继续从'UIView'继承。 – 2012-03-17 14:30:23
试试这个,
id graphv;
if ([type isEqualoString:@"day"]) {
(GraphDayView *)graphv = [[GraphDayView alloc] initWithFrame:rect];
} else {
(GraphMonthView*)graphv = [[GraphMonthView alloc] initWithFrame:rect];
}
这样做可能会使代码更平滑,但更容易出错。但是,graphv仍然是id类型的对象,编译器在访问属性或调用GraphDayView甚至UIView的方法时仍会引发警告。当使用ARC时,编译器甚至会抛出错误并停止构建过程。 – 2012-03-17 14:46:02
很多的通用超建议被做了最适合liekly。
如果他们不是,那么你可以使用typcasts。但是,类型转换可能会导致像未知选择符或bad_exec这样的异常。如果您想要节省地使用typcast,那么您应该始终检查isKindOfClass或respondsToSelector。
样本:
id someClassObject; //或任何其他常见的超类*代替id
如果([something is True]) someClassObject = [[AClass alloc] init]; //假设ARC。如果没有,那么你也可能想在这里保留/ autorelease。 else someClassObject = [[AClass alloc] init];
... //一些代码
如果([someClassObject isKindOfClass:[ACLASS类]]) [(ACLASS *)someClassObject methodOfAClass];如果([someClassObject isKindOfClass:[AClass class]]){ AClass * aClassTemp =(AClass *)someClassObject; [aClassTemp methodOfAClass]; aClassTemp。propertyOfAClass = someValue; }
如果([someClassObject respondsToSelector:@selector(methodOfBClass :)) [someClassObject perforformSelector:@selector(methodOfBClass :) withObject:的UIColor clearColor]];
注意:选择器名称后面的数字与方法的参数数量相关。对于每个可能的方法调用,您可能找不到适当的performSelector差异。特别是你可以只传递或返回对象的引用。
再次,他们两个我只会建议如果共同的子类不适合你的情况。
通常你在这种情况下使用一个通用的基类,这是可能的吗? – 2012-03-17 13:57:09