可以将对象从IF语句范围中传出吗?

时间:2013-11-22 00:35:39

标签: objective-c if-statement

这是我的代码。编译器抱怨范围内未使用的变量,并使用未声明的变量超出范围。我明白那个。该对象需要在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对象?

2 个答案:

答案 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];

另外,如果你的两个班级有相同的方法等,这并不意味着你应该看一个重构

值得一读https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html

答案 1 :(得分:2)

你说:

  

MALInterfaceController和MALControllerUnofficial基本上是具有相同方法等的同一类,但是针对两个不同的API进行了定制。

你想考虑(a)使用公共基类(b)使用协议或者(c)使用类集群 - 最后一个更加模糊,所以我们将跳过那个。采用其中任何一个都可以解决您的问题。

(a)共同基类。使用代码定义一个类,该代码是对象的通用版本,比如说MALControllerGeneric,然后创建MALInterfaceControllerMALControllerUnofficial作为子类,为两个不同的案例定制通用版本。在if声明interfaceMALControllerGeneric类型之前。

(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:吗?