Reputation: 1892
Here's my code. The compiler is complaining about unused variables within the scope, and use of an undeclared variable out of scope. I understand that. The object would need to be declared before the IF statement so it's accessible from both sides. But here's the twist.
I can't pre-declare the object because what class the object will be from is dependent on the result of the IF statement. Here's the excerpt of code that I'm stuck on.
if (!([self.defaults valueForKey:@"unofficialAPIOn"])) {
MALInterfaceController *interface = [[MALInterfaceController alloc]init];
}
else{
MALControllerUnofficial *interface = [[MALControllerUnofficial alloc]init];
}
[interface verifyAuth:self.usernameField.text forPassword:self.passwordField.text];
Both MALInterfaceController and MALControllerUnofficial are basically the same class that have the same methods, etc but are tailored to two different API's. How can I pass the *interface object upwards?
Upvotes: 0
Views: 267
Reputation: 53000
You state:
Both MALInterfaceController and MALControllerUnofficial are basically the same class that have the same methods, etc but are tailored to two different API's.
You want to consider (a) using a common base class (b) using a protocol or maybe (c) using a class cluster - the last is more obscure so we'll skip that one. Adopting any of these will address your problem.
(a) Common base class. Define a class with the code that is a generic version of what your object does, say MALControllerGeneric
, and then create MALInterfaceController
and MALControllerUnofficial
as subclasses which tailor the generic version for the two different cases. Before your if
declare interface
to be of type MALControllerGeneric
.
(b) Declare the common methods your two classes must provide as a protocol, this lists the methods an class conforming to the protocol must implement. Then declare your two classes as implementing this protocol. In outline this is:
@protocol MALController
- (void) someCommonProcedure;
// etc.
@end
// inherit from NSObject, implement MALController protocol
@interface MALInterfaceController : NSObject<MALController>
// declare methods peculiar to MALInterfaceController (if any)
@end
@implementation MALInterfaceController
// implement protocol
- (void) someCommonProcedure { ... }
...
@end
You then declare interface
to be any object which implements the protocol:
id<MALController> interface;
This improves (static) type-checking compared to use the more generic id
type.
The choice between (a) and (b) depends on factors such as how much common code can be shared etc., there is no general right answer - you have to pick what suits.
Addendum - After Comment
Using the protocol approach, you should have the code along the lines of:
id<MALController> interface;
if (![self.defaults valueForKey:@"unofficialAPIOn"])
interface = [MALInterfaceController new];
else
interface = [MALControllerUnofficial new];
[interface verifyAuth:self.usernameField.text forPassword:self.passwordField.text];
BTW did you mean to call boolForKey:
rather than valueForKey:
above?
Upvotes: 2
Reputation: 3997
Why not use the dynamic type id?
id interface;
if (!([self.defaults valueForKey:@"unofficialAPIOn"])) {
interface = [[MALInterfaceController alloc]init];
}
else{
interface = [[MALControllerUnofficial alloc]init];
}
(id<protocolWhichBothClassesConformTo>)[interface verifyAuth:self.usernameField.text forPassword:self.passwordField.text];
Also, does this not mean you should be looking at a refactor if two of your classes have 'same methods etc'
Upvotes: 5