Reputation: 1077
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?"). That means I have to define the object before the if-else block, but which type of object I have to use? If I use id
there will be errors on myObj.property = TRUE;
, if I use ClassOne
or ClassTwo
there will be some warnings regarding incompatible pointer assignment. 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)
Upvotes: 0
Views: 100
Reputation: 5237
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. You won't have to add too many if-else statements. Instead you just make sure the object that comes in, conforms to your protocol.
Upvotes: 2
Reputation: 15213
It depends on the situation. For example why do you need myObj
outside the if-else statement? 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). 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
Upvotes: 0
Reputation: 38239
As scope of myObj limit to if block so use in if block only. Now if myObj defined outside of if block then object can't have same name.
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;
}
}
Upvotes: 0
Reputation: 3805
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;
}
}
Upvotes: -1
Reputation: 1495
You can use id to init your classes and cast them later to the correct custom class before setting the .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
}
}
Upvotes: 1