【问题标题】:Difference between @[] and [NSArray arrayWithObjects:] [duplicate]@[] 和 [NSArray arrayWithObjects:] 之间的区别 [重复]
【发布时间】:2012-10-01 19:39:38
【问题描述】:

可能重复:
Should I prefer to use literal syntax or constructors for creating dictionaries and arrays?

两者有什么区别:

NSArray *array = @[@"foo", @"bar"];

NSArray *array = [NSArray arrayWithObjects:@"foo", @"bar", nil];

其中一个更稳定、更快还是其他?

【问题讨论】:

    标签: objective-c nsarray objective-c-literals


    【解决方案1】:

    这个documentation 没有直接提到效率,但确实提到了

    NSArray *array = @[@"foo", @"bar"];
    

    等价于

    NSString *strings[3];
    strings[0] = @"foo";
    strings[1] = @"bar";
    NSArray *array = [NSArray arrayWithObjects:strings count:2];
    

    我不得不假设在装配级别上,两者是相同的。

    因此,唯一的区别是偏好。我更喜欢前者,打字更快,理解更直接。

    【讨论】:

      【解决方案2】:

      第一个只是第二个的语法糖。它稍微好一点,因为它更短并且不需要哨兵nil 来标记列表的末尾。 (当您使用第二个变体并忘记nil 时,您会得到一些非常不可预测的行为。)

      如果它们都没有生产相同的组件,那么性能差异将非常小,任何人都不会担心。这就是程序集使用文字速记查找第一种情况的方式:

      // NSArray *bar = @[@"bar"];
      movl    %edi, -40(%ebp)
      movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%esi), %eax
      movl    L_OBJC_SELECTOR_REFERENCES_4-L0$pb(%esi), %edi
      movl    %eax, (%esp)
      movl    %edi, 4(%esp)
      movl    %edx, 8(%esp)
      movl    $1, 12(%esp)
      movl    %ecx, -76(%ebp)         ## 4-byte Spill
      calll   L_objc_msgSend$stub
      movl    %eax, (%esp)
      calll   L_objc_retainAutoreleasedReturnValue$stub
      movl    %eax, -36(%ebp)
      

      arrayWithObjects 就是这种情况:

      // NSArray *foo = [NSArray arrayWithObjects:@"foo", nil];
      movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%ecx), %eax
      movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%ecx), %edi
      movl    %eax, (%esp)
      movl    %edi, 4(%esp)
      movl    %edx, 8(%esp)
      movl    $0, 12(%esp)
      movl    %esi, -72(%ebp)         ## 4-byte Spill
      calll   L_objc_msgSend$stub
      movl    %eax, (%esp)
      calll   L_objc_retainAutoreleasedReturnValue$stub
      movl    $1, %ecx
      leal    -40(%ebp), %edx
      movl    -64(%ebp), %esi         ## 4-byte Reload
      leal    L__unnamed_cfstring_2-L0$pb(%esi), %edi
      movl    %eax, -32(%ebp)
      

      我对组装的了解不够多,无法得出结论,但它们看起来确实具有可比性。

      【讨论】:

      • 试试 [NSArray arrayWithObject:@"bar"];这应该与 @[@"bar"]; 相同
      • 臭虫,在 W3C 他们说编译器会以同样的方式解释这一点。
      • +1 用于汇编翻译。
      【解决方案3】:

      这是 Objective C 3.0 中新发明的功能

      编译器基本上将快捷方式替换为[NSArray arrayWithObjects:...] 语句。

      字符串@"String"也是如此

      编辑:好的,假设发生了类似的事情:) 基本字符串实际上没有其他构造函数。

      【讨论】:

      • 字符串大小写实际上是不同的。没有转换为构造方法;该对象是二进制文件的静态部分。
      猜你喜欢
      • 2014-08-16
      • 2011-04-08
      • 2012-11-24
      • 2013-06-05
      • 2021-09-29
      • 2020-05-27
      • 2016-03-23
      • 2012-08-11
      • 2012-11-24
      相关资源
      最近更新 更多