4

我有:

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`.

循环块永远不会改变server

servers是一个NSMutableArraywith 字典,一个在循环期间没有改变的属性。

为什么循环结束后server有值?nil

是我第一次在循环之后使用这样的变量。没有想太多,我认为它会像(在旧的 C 时代)一样工作:

int i;
for (i = 0; i < n; i++)
{
    ...
}
4

3 回答 3

7

语言定义循环退出时循环变量将设置为 nil。该语言没有说明循环变量将具有最后一个值,恰恰相反。

在幕后,这是有充分理由的。快速迭代对基础数据做出假设。例如,当您迭代一个可变数组时,该数组可能不会在您迭代时被修改。快速迭代很快,除其他外,因为它不保留和释放循环变量。相反,它依赖于底层对象(例如数组)来保存引用。

但是一旦循环退出,该底层对象就不再提供任何保证。数组可能会消失,或者最后使用的数组元素可能会被删除。所以编译器要么必须保留变量,要么将其设置为 nil。设置为 nil 更快。

于 2016-07-18T21:36:10.297 回答
5

a 中使用的变量for-loop将始终nil在循环结束时使用(除非循环被break语句中断,如@rmaddy 所指出的那样)。

另一种避免误解的循环方法是:

for (NSDictionary* server in self.servers)
{
    //... server is not nil
}
//here server doesn't exist (out of scope)

如果你想将 self.servers 的值保存在循环之外的 var 中,你必须这样做:

NSDictionary* serverSave;

for (NSDictionary* server in self.servers)
{
    serverSave = server;
}
//here you can use serverSave, which will contain the last value of self.servers

希望这可以帮助。

于 2016-07-18T20:23:24.293 回答
-1

它在循环之后为 nil,因为带有 ARC 的 Objective-C 将它取消(请参阅Objective C 中“for in”循环之后的循环变量的值)。

因此,当您到达终点时:

NSDictionary* server; // server is nil here

for (server in self.servers)
{
    ... // Does not set server to nil.
}

server将为零。

如果您正在寻找某个值,您可以这样做:

NSDictionary *dict;

for (NSDictionary* server in self.servers)
{
    if (server == whatever you want){
        dict = server;
        break;
    }
}

或者只获取最后一个值:

NSDictionary *dict;

for (NSDictionary* server in self.servers)
{
    dict = server;
}
于 2016-07-18T20:44:15.583 回答