【问题标题】:Why Doesn't NSArray return NULL for nonexistent indexes?为什么 NSArray 不为不存在的索引返回 NULL?
【发布时间】:2012-05-28 08:13:07
【问题描述】:

据我了解,Objective C 的特别之处之一是您可以将消息发送到 NULL,它只会忽略它们而不是崩溃。

为什么如果请求的索引超出范围,NSArray 不只是返回 NULL 对象,而不是导致 NSRangeException?

我对 Objective C 和 NSArray 的期望如下。

NSArray *array = [NSArray arrayWithObjects:@"Object 1", @"Object 2", @"Object 3", nil];

for (int i = 0; i < 5; i++) {
    NSString *string  = [array objectAtIndex:i];

    if (string) {
        NSLog(@"Object: %@",string);
    }
}

允许我使用不包含对象并简单地返回 NULL 来访问数组的索引。然后我可以检查对象是否存在。我可以在其他地方执行此操作,例如检查对象是否已实例化。

NSArray *array;

if (!array) {
    array = [NSArray array];
}

我意识到这是一个基于理论的问题,但我很好奇 :)

【问题讨论】:

  • Messaging nil 与请求越界索引完全不同。我不明白你为什么要在这里建立联系。
  • 因为它没有意义。访问程序分配之外的内存是未定义的行为。未定义的行为不应该是程序所依赖的东西,相反,它应该是程序努力删除的东西。现在,诚然,NSArray 不是数组,但在大多数情况下它必须遵循数组的范式。

标签: objective-c cocoa nsarray


【解决方案1】:

Messages to nil 是语言级别的功能,而不是框架 API 功能。

NSArray(和其他类)抛出异常以指示程序员错误是设计 API 时(~1993 年)有意识的设计决定。正如 Kevin 和 Richard 所指出的,nil eats message 无论如何都没有错误,而out of bounds 则在很大程度上是错误输入的情况。

你会在哪里画线? substringWithRange: 应该接受任何旧输入吗? setObject:atIndex:呢?

通过使 NSArray @throw on bounds exceptions for indexOfObject: 它使 API 保持一致; 任何超出范围的索引(或范围)都将@throw

【讨论】:

  • 好的,谢谢你的解释。正是我需要的那种东西。我是一名自学成才的程序员,没有接受过 CS 教育,所以这正是我所需要的。
  • 当然——API 设计有很多微妙之处。在许多情况下,将看似奇怪的决定放在更大的背景下会很有意义。 API 设计和语言设计很难做好!
【解决方案2】:

您可以使用NSMutableDictionary 来完成您想做的事情。将键设置为NSNumber 索引。对不存在的键(超出我们想象的范围或已删除)调用 objectForKey 将返回 nil。

【讨论】:

  • 谢谢,不是专门寻找解决方案来使它工作我一直有解决方法,我有更合适的方法来处理它。只是好奇。赞成尝试解决一个不存在的问题!大声笑
  • 这与另一个事实有关,即您不能拥有稀疏数组。响应 -objectForKey: 返回 nil 的数组表明该索引处有一个空位置,而不是索引本身无效。另请注意,如果键为 nil,[-NSDictionary objectForKey:] @throws。
  • 这也使得 NSMutableDictionary 成为一个很好的候选者,可以在需要时用作稀疏数组。
猜你喜欢
  • 2016-12-28
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多