Reputation: 149
I want to create a object but the type depends on the result of the if-condition:
if ([type isEqualToString:@"day"]) {
GraphDayView *graphv = [[GraphDayView alloc] initWithFrame:rect];
} else {
GraphMonthView *graphv = [[GraphMonthView alloc] initWithFrame:rect];
}
The problem is that graphv is out of scope, so I am not able to use it after the if-statement. So I tried to declare it as an id:
id graphv;
if ([type isEqualToString:@"day"]) {
graphv = [[GraphDayView alloc] initWithFrame:rect];
} else {
graphv = [[GraphMonthView alloc] initWithFrame:rect];
}
But the problem now is, that the compiler doesn't know what kind of object grapv is. So:
graphv.backgroundColor = [UIColor whiteColor];
gives an error. Anyone an idea how to solve this one?
Upvotes: 0
Views: 203
Reputation: 14068
A lot of suggestions for a common superclass have been made which are most liekly suitable.
In the event they are not then you could use typcasts. However, typecasts may cause exceptions like unknown selecor or bad_exec. If you want to savely use typcasts then you should always check either isKindOfClass or respondsToSelector.
Sample:
id someClassObject; //or any other common superclass* instead of id
If ([something isTrue]) someClassObject = [[AClass alloc] init]; //assuming ARC. If not then you may want to retain/autorelease here too. else someClassObject = [[AClass alloc] init];
... //some code
if ([someClassObject isKindOfClass:[AClass class]]) [(AClass *) someClassObject methodOfAClass];
// if ([someClassObject isKindOfClass:[AClass class]]) { AClass *aClassTemp = (AClass *) someClassObject; [aClassTemp methodOfAClass]; aClassTemp.propertyOfAClass = someValue; }
if ([someClassObject respondsToSelector:@selector(methodOfBClass:)) [someClassObject perforformSelector:@selector(methodOfBClass:) withObject:[UIColor clearColor]];
Note the number of : following the selector name correlates to the number of parameters of the method. You may not find a suitable variance of performSelector for each possible method call. Especially as you can pass or return references to objects only.
Again, both of them I would only suggest if the common subclass is not suitable in your case.
Upvotes: 0
Reputation: 4257
Try this,
id graphv;
if ([type isEqualoString:@"day"]) {
(GraphDayView *)graphv = [[GraphDayView alloc] initWithFrame:rect];
} else {
(GraphMonthView*)graphv = [[GraphMonthView alloc] initWithFrame:rect];
}
Upvotes: 0
Reputation: 47729
Make GraphDayView and GraphMonthView both subclasses of GraphCalendarView. Then make your backgroundColor
a property of GraphCalendarView.
(Or, if your two classes are already subclasses of a UI class that implements backgroundColor
then you're home free.)
Declare your variable as GraphCalendarView graphv;
, and then proceed as before. If you need to use a property/method that's unique to of one or the other of your two derived classes then cast to that class first.
Upvotes: 1
Reputation: 8720
If they share the same superclass, then use that instead of id. Otherwise, create two variables and set them to nil:
GraphDayView *gdv = nil;
GraphMonthView *gmv = nil;
Then test after the if statement to see which one was initialized.
Upvotes: 2