这是我的代码。编译器抱怨范围内未使用的变量,并使用未声明的变量超出范围。我明白那个。该对象需要在IF语句之前声明,因此可以从双方访问它。但这是扭曲。
我不能预先声明对象,因为对象将来自哪个类取决于IF语句的结果。这是我坚持使用的代码摘录。
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];
MALInterfaceController和MALControllerUnofficial基本上都是具有相同方法等的类,但是针对两个不同的API进行了定制。如何向上传递* interface对象?
答案 0 :(得分:5)
为什么不使用动态类型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];
另外,如果你的两个班级有相同的方法等,这并不意味着你应该看一个重构
答案 1 :(得分:2)
你说:
MALInterfaceController和MALControllerUnofficial基本上是具有相同方法等的同一类,但是针对两个不同的API进行了定制。
你想考虑(a)使用公共基类(b)使用协议或者(c)使用类集群 - 最后一个更加模糊,所以我们将跳过那个。采用其中任何一个都可以解决您的问题。
(a)共同基类。使用代码定义一个类,该代码是对象的通用版本,比如说MALControllerGeneric
,然后创建MALInterfaceController
和MALControllerUnofficial
作为子类,为两个不同的案例定制通用版本。在if
声明interface
为MALControllerGeneric
类型之前。
(b)声明两个类必须提供的公共方法作为协议,这列出了协议必须实现的符合的类的方法。然后将您的两个类声明为实现此协议。概括地说,这是:
@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
然后,您将interface
声明为实现协议的任何对象:
id<MALController> interface;
与使用更通用的id
类型相比,这改进了(静态)类型检查。
(a)和(b)之间的选择取决于诸如可以共享多少公共代码等因素,没有一般正确的答案 - 你必须选择适合的。
附录 - 评论后
使用协议方法,你应该有以下代码:
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你的意思是打电话给boolForKey:
而不是valueForKey:
吗?