0

给定以下代码:

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;
}

编译器将引发关于myObj(未声明的标识符)的错误,这在某种程度上是显而易见的(“如果两个条件都为假,我该怎么办?”)。这意味着我必须在 if-else 块之前定义对象,但我必须使用哪种类型的对象?如果我使用id会有错误myObj.property = TRUE;,如果我使用ClassOneorClassTwo会有一些关于不兼容指针分配的警告。我应该使用其他方式而不是给定的代码吗?

谢谢你。

(注意:该片段是在没有使用语法检查或测试的情况下编写的,因此它可能包含错误)

4

5 回答 5

2

协议怎么样?

@protocol MyProtocol

@property (assign, nonatomic) BOOL myProperty;

@end

然后:

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

这是我能想到的最干净、最短的解决方案。您不需要强制转换,而是利用 Objective-c 动态绑定的强大功能。您不必添加太多 if-else 语句。相反,您只需确保传入的对象符合您的协议。

于 2012-08-31T12:30:33.063 回答
1

您可以使用 id 来初始化您的类,然后在设置 .property = TRUE 之前将它们转换为正确的自定义类

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
    }
}
于 2012-08-31T12:24:16.663 回答
0

由于 myObj 的范围仅限于 if 块,因此仅在 if 块中使用。现在,如果 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;
 }
}
于 2012-08-31T12:25:50.640 回答
0

这取决于实际情况。例如,为什么需要myObj在 if-else 语句之外?如果您需要将它传递给另一个方法,您可以创建一个基类,例如 exClassBase和 makeClassOneClassTwo继承ClassBase,然后让您的方法接受ClassBase作为参数(当然,如果两个对象有共同点)。如果不是这种情况,那么在每个语句中执行逻辑有什么问题:

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
于 2012-08-31T12:27:24.987 回答
-1
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;
    }

}
于 2012-08-31T12:24:25.337 回答