简体   繁体   English

在if-else块中确定对象类型

[英]Deciding object type in an if-else block

Given the following code: 给出以下代码:

for (id object in anArray){
    if ([object isKindOfClass:[ClassOne class]]){
       ClassOne *myObj = [[ClassOne alloc] init];
    }else if ([object isKindOfClass:[ClassTwo class]]){
       ClassTwo *myObj = [[ClassTwo alloc] init];
    }
    myObj.property = TRUE;
}

the compiler will raise an error regarding myObj (undeclared identifier), which is somehow obvious ("what should I do if both conditions will be false?"). 编译器会引发关于myObj (未声明的标识符)的错误,这在某种程度上是显而易见的(“如果两个条件都为假,我该怎么办?”)。 That means I have to define the object before the if-else block, but which type of object I have to use? 这意味着我必须在if-else块之前定义对象,但是我必须使用哪种类型的对象? If I use id there will be errors on myObj.property = TRUE; 如果我使用idmyObj.property = TRUE;会出错myObj.property = TRUE; , if I use ClassOne or ClassTwo there will be some warnings regarding incompatible pointer assignment. ,如果我使用ClassOneClassTwo ,会有一些关于不兼容指针赋值的警告。 Should I use some other way instead of the given code? 我应该使用其他方式而不是给定的代码吗?

Thank you. 谢谢。

(note: the snippet was written without using syntax checking or testing it, so it may contains errors) (注意:代码片段是在不使用语法检查或测试的情况下编写的,因此可能包含错误)

How about a protocol? 协议怎么样?

@protocol MyProtocol

@property (assign, nonatomic) BOOL myProperty;

@end

Then: 然后:

for (id anObject in anArray){
    if ([anObject conformsToProtocol:@protocol(MyProtocol)]) {
        Class clazz = [anObject class];
        id<MyProtocol>  myObject = [[clazz alloc] init];
        myObject.myProperty = YES;
    }
}

This is the cleanest and shortest solution I can think of. 这是我能想到的最干净,最短的解决方案。 You won't need to cast, instead you will harness the power of objective-c's dynamic binding. 你不需要施放,而是利用objective-c动态绑定的力量。 You won't have to add too many if-else statements. 您不必添加太多if-else语句。 Instead you just make sure the object that comes in, conforms to your protocol. 相反,您只需确保进入的对象符合您的协议。

You can use id to init your classes and cast them later to the correct custom class before setting the .property = TRUE 在设置.property = TRUE之前,您可以使用id初始化类并稍后将它们转换为正确的自定义类

for (id object in anArray){
    id myObj;
    if ([object isKindOfClass:[ClassOne class]]){
        myObj = [[ClassOne alloc] init];
    }else if ([object isKindOfClass:[ClassTwo class]]){
        myObj = [[ClassTwo alloc] init];
    }

    if ([object isKindOfClass:[ClassOne class]]){
        ((ClassOne *)myObj).property = TRUE;
    }else if ([object isKindOfClass:[ClassTwo class]]){
        ((ClassTwo *)myObj).property = FALSE; // or whatever
    }
}

As scope of myObj limit to if block so use in if block only. 由于myObj的范围限制为if块,因此仅在if块中使用。 Now if myObj defined outside of if block then object can't have same name. 现在,如果myObj在if块之外定义,则对象不能具有相同的名称。

for (id object in anArray){
 if ([object isKindOfClass:[ClassOne class]]){
   ClassOne *myObj = [[ClassOne alloc] init];
   myObj.property = TRUE;
 }else if ([object isKindOfClass:[ClassTwo class]]){
   ClassTwo *myObj = [[ClassTwo alloc] init];
   myObj.property = TRUE;
 }
}

It depends on the situation. 这取决于实际情况。 For example why do you need myObj outside the if-else statement? 例如,为什么在if-else语句之外需要myObj If you need to pass it to another method you can create a base class, for ex ClassBase and make ClassOne and ClassTwo to inherit from ClassBase and then make your method accept ClassBase as an argument (that's of course if both objects have something in common). 如果你需要将它传递给另一个方法,你可以为ClassBase创建一个基类,让ClassOneClassTwoClassBase继承,然后让你的方法接受ClassBase作为参数(当然,如果两个对象都有共同点) 。 If that's not the case, what's the problem to do your logic in every statement: 如果不是这样,那么在每个陈述中做出逻辑的问题是什么:

if ([object isKindOfClass:[ClassOne class]]){
       ClassOne *myObj = [[ClassOne alloc] init];
       myObj.property = YES;
       [self doSomethingWith:myObj];
 }else if ([object isKindOfClass:[ClassTwo class]]){
       ClassTwo *myObj = [[ClassTwo alloc] init];
       myObj.otherProperty = YES;
       [self doSomethingElseWith:myObj];
    }
//end of method
for (id object in anArray){
    if ([object isKindOfClass:[ClassOne class]]){
        ClassOne *myObj = [[ClassOne alloc] init];
        myObj.property = TRUE;
    }
    else if ([object isKindOfClass:[ClassTwo class]]){
        ClassTwo *myObj = [[ClassTwo alloc] init];
        myObj.property = TRUE;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM