2

Is the value of the loop variable in a for - in loop guaranteed to be nil after the loop executes, as long as the loop does not contain a break statement? For example, I'd like to write code like the following:

NSArray *items;
NSObject *item;
for (item in items) {
   if (item matches some criterion) {
      break;
   }
}
if (item) {
   // matching item found. Process item.
}
else {
   // No matching item found.
}

But this code depends on item being set to nil when the for loop runs all the way through with no break.

Will Nelson
  • 966
  • 8
  • 13

3 Answers3

2

Another solution would be to check the array objects passing a specific test instead. You seem to break on the first occurrence so I only get one index back as well. If you want all matches you could use indexesOfObjectsPassingTest: instead.

NSUInteger index = [items indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    if (/* check the item*/) {
        *stop = YES;
    }
}];

if (index == NSNotFound) {
    // no match was found
} else {
    // at least one item matches the check
    id match = items[index];
}
David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
1

You should instead use this:

id correctItem = nil;
for (id item in items) {
    if (item matches some criteria) {
        correctItem = item;
        break;
    }
}
bneely
  • 9,083
  • 4
  • 38
  • 46
1

With ARC enabled, your Objective-C object pointer variables will be set to nil regardless of where you create them. [Source]

If you are not using ARC, you can assign the pointer to nil explicitly:

NSArray *items;
NSObject *item = nil;  //<- Explicitly set to nil
for (item in items) {
   if (item matches some criterion) {
      break;
   }
}
if (item) {
   // matching item found. Process item.
}
else {
   // No matching item found.
}

I don't know the exact case, but couldn't you just do this, doing the work inside the for loop:

NSArray *items;
NSObject *item; //Doesn't really matter about item being set to nil here.
for (item in items) {
   if (item matches some criterion) 
   {
       // matching item found. Process item.
      break;
   }
}
//Don't have to worry about item after this
Community
  • 1
  • 1
James Webster
  • 31,873
  • 11
  • 70
  • 114