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が、これはどういうわけか明白です (「両方の条件が false になる場合はどうすればよいですか?」)。つまり、if-else ブロックの前にオブジェクトを定義する必要がありますが、どのタイプのオブジェクトを使用する必要があるのでしょうか? を使用idすると でエラーが発生し、またはmyObj.property = TRUE;を使用すると互換性のないポインター割り当てに関する警告が表示されます。指定されたコードの代わりに他の方法を使用する必要がありますか?ClassOneClassTwo

ありがとうございました。

(注: スニペットは構文チェックやテストを使用せずに記述されているため、エラーが含まれている可能性があります)

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

状況によります。たとえば、なぜmyObjif-elseステートメントの外側が必要なのですか?それを別のメソッドに渡す必要がある場合は、exとmakeの基本クラスを作成し、そこClassBaseから継承して、メソッドを引数として受け入れるようにすることができます(もちろん、両方のオブジェクトに共通点がある場合)。そうでない場合、すべてのステートメントでロジックを実行する際の問題は何ですか。ClassOneClassTwoClassBaseClassBase

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 に答える
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 に答える
-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 に答える