Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does loop variable become `nil` after loop

I have:

NSDictionary* server;

for (server in self.servers)
{
    if (<some criterium>)
    {
        break;
    }
}

// If the criterium was never true, I want to use the last item in the
// the array. But turns out that `server` is `nil`.

The loop block never changes server.

servers is an NSMutableArray with dictionaries, a property that's not changed during the loop.

Why does server have the value nil after the loop has ended?

Was the first time I used such a variable after the loop. Without thinking too much, I assumed it would work like (in the old C days):

int i;
for (i = 0; i < n; i++)
{
    ...
}
like image 224
meaning-matters Avatar asked Dec 18 '22 15:12

meaning-matters


1 Answers

The language defines that the loop variable will be set to nil when the loop exits. The language doesn't state that the loop variable will have the last value, quite the opposite.

Behind the scenes, there is a very good reason for that. Fast iteration makes assumptions about the underlying data. For example, when you iterate over a mutable array, the array may not be modified while you iterate. Fast iteration is fast, among other things, because it doesn't retain and release the loop variable. Instead it relies on the underlying object (for example an array) to hold a reference.

But once the loop exits, that underlying object gives no guarantees anymore. The array could go away, or the array element that was last used might get deleted. So the compiler either must retain the variable, or set it to nil. Setting to nil is quicker.

like image 148
gnasher729 Avatar answered Jan 02 '23 23:01

gnasher729