Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

for loops - Object type disregarded?

I sometimes like to organize IB elements into NSArrays primarily to help me organize my elements. Most often, different classes of objects make it into the same array with each other. While this is a convenient way of organization, I can't seem to wrap my head around why if I have an array like this:

NSArray *array = [NSArray arrayWithObjects:((UITextField *)textField), ((UISegmentedController *)segmentedController), nil];

Why I get "Does not respond to selector" messages when I put a for loop like this:

for (UITextField *text in array) {
    [text setText:@""];
}

The for loop seems to be passed objects that are not of class UITextField.

What is the point of declaring the object's class if all objects in the specified array are passed through the loop?

EDIT Just for reference, this is how I'm handling it as of now:

for (id *object in array) {
    if ([object isMemberOfClass:[UITextField class]]) {
        foo();
    } else if ([object isMemberOfClass:[UISegmentedController class]) {
        bar();
    }
 }
like image 941
esqew Avatar asked Aug 17 '11 21:08

esqew


People also ask

Can you use a for loop on an object?

If you have an array that is considered to be an object in javascript, you can't loop through the array using map(), forEach(), or a for..of loop.

What's the difference between Forin and for of?

Both for...in and for...of statements iterate over something. The main difference between them is in what they iterate over. The for...in statement iterates over the enumerable string properties of an object, while the for...of statement iterates over values that the iterable object defines to be iterated over.


2 Answers

When you do

for (UITextField *text in...

the object pointers from the array are cast to UITextField* type - so if the object isn't actually a UITextField, all sorts of weird things may happen if you try to call UITextField methods.

So instead use the id type (no * needed, btw):

for (id obj in array)

Then check the type as you do and call the appropriate methods. Or, filter the array to get only objects of a certain type, then go though that type only:

for (UITextField* text in [array filteredArrayUsingPredicate:...])

Edit: here's how to build class filter predicates:

Is it possible to filter an NSArray by class?

like image 142
SVD Avatar answered Sep 19 '22 23:09

SVD


What is the point of declaring the object's class if all objects in the specified array are passed through the loop?

The class name is just there to let the compiler know what it should expect to find. This allows it to try to figure out what methods it should expect you to call and how you might treat the object. It's the same idea as passing in an int to a method that takes float. The method will not ignore ints - it's assuming you're passing the correct type. You're just giving this construct a little more credit than it's due:

for (UITextField *text in array)

It just doesn't have that functionality. How you're handling it now is the correct way.

like image 41
Luke Avatar answered Sep 19 '22 23:09

Luke