Objective-C:拳击 VS 文字

Objective-C: Boxing VS Literal

我应该使用哪个结构,为什么?我将用 NSArray 做一个例子。这同样适用于其他 "boxed" 个对象,例如 NSDictionaryNSNumber...

NSArray *arr1 = @[object1, object2, object3];

NSArray *arr2 = [NSArray arrayWithObjects:object1, object2, object3, nil];

这两个构造对 NSArrayNSDictionary 对象产生相同的效果。不同之处在于第一种语法在 2012 版编译器之前不可用,而 arrayWithObjects: 适用于该语言的所有版本。

如果您不打算让您的代码使用旧版本的编译器进行编译,那么新语法会为您提供更好的可读性,尤其是对于 NSNumber 对象。比较

NSArray *arr = @[@1, @2, @3];

对比

NSArray *arr = [NSArray arrayWithObjects:
    [NSNumber numberWithInteger:1]
,   [NSNumber numberWithInteger:2]
,   [NSNumber numberWithInteger:3]
,   nil
];

NSArrayNSDictionary 文字都不是 "boxed"。装箱是指用标量或非对象类型制作对象。 Cocoa 数组和字典始终是对象。

拳击 NSNumber 的相关术语。例如,1 是一个 int,一个标量类型(不是对象)。 @1是一个NSNumber,装箱1的结果。但是,从技术上讲,我会说 [NSNumber numberWithInt:1] 也是拳击。只是 @1 是一种更方便的语法。

有区别:

NSArray *arr1 = @[object1, object2, object3];

NSArray *arr2 = [NSArray arrayWithObjects:object1, object2, object3, nil];

首先,如果 object1object2object3 中的任何一个保持 nil,您将获得运行时异常。在第二个中,任何 nil 只是终止参数列表。因此,如果 object2nilarr2 将最终成为仅包含 object1 的单元素数组。 NSArray 永远不会考虑 object3 因为,就它而言,参数列表在第一个元素之后终止。

很少,您可以合法地使用此行为(在这种情况下,我会在评论中清楚地注明),但大多数情况下这是意外和不受欢迎的行为。这是一种特别有害的错误。