【问题标题】:Push object onto end of array using new literal syntax使用新的文字语法将对象推送到数组的末尾
【发布时间】:2012-10-15 07:07:46
【问题描述】:

PHP 有:

arr[] = 'Push this onto my array';

字符串将被添加到数组末尾的位置。

在新的 Objective-C 文字语法中是否有任何等价物?我能想到的最简洁的方法是:

arr[arr.count] = @"Add me";

但也许那里有更好的东西?

【问题讨论】:

    标签: objective-c nsmutablearray objective-c-literals


    【解决方案1】:

    看看the documentation for the new literal syntax。当您使用下标分配给数组时,调用将被转换为setObject:atIndexedSubscript: 方法调用:

    NSMutableArray *foo = …;
    foo[0] = @"bar"; // => [foo setObject:@"bar" atIndexedSubscript:0];
    

    如果您有自己的可变数组实现,您可以在setObject:atIndexedSubscript: 方法中添加一个特殊情况,以便在分配超过数组大小时增加数组。 我非常怀疑默认的 NSMutableArray 实现会做类似的事情,很可能你只会得到一个关于索引超出范围的异常。这确实是 NSMutableArray 所做的,请参阅 @ 987654322@:

    如果索引等于count,则将元素添加到末尾 数组,增加数组。

    感谢 Martin 的提醒!

    【讨论】:

    • NSMutableArraysetObject:atIndexedSubscript: 文档明确指出:“如果索引等于 count,则将元素添加到数组的末尾,从而扩大数组。”
    【解决方案2】:

    我实际上并不推荐这样做,但 Objective-C 确实 可以使用您自己的代码扩展 setObject:atIndexedSubscript: 方法。这个过程被称为“方法调配”,这里有解释:http://darkdust.net/writings/objective-c/method-swizzling

    这里有一些演示该过程的实际工作代码。最酷的是main(),我可以在其中使用fib[-1] = ... 而不是fib[fib.count] = ...。当然,这里没有很大的优势;代码不再高效,当然也更难阅读。但我确实省去了两次写出“fib”的麻烦。

    这种方法的一个主要缺点是Objective-C实际上并没有任何关于加载类别的顺序的规则,所以如果其他人提供了具有类似功能的类别,它会是一个最后加载的折腾。 (如果他们碰巧为他们的类别选择了相同的名称,我认为这将是一个完全加载的折腾。)

    所以,最重要的是,不要这样做:但这是可能的。

    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    
    @interface NSMutableArray (NegativeOne)
    +(void)load;
    -(void)swizzled_setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
    @end
    
    @implementation NSMutableArray (NegativeOne)
    
    +(void)load
    {
        Method original = class_getInstanceMethod(self, @selector(setObject:atIndexedSubscript:));
        Method swizzled = class_getInstanceMethod(self, @selector(swizzled_setObject:atIndexedSubscript:));
        method_exchangeImplementations(original, swizzled);
    }
    
    -(void)swizzled_setObject:(id)obj atIndexedSubscript:(NSUInteger)idx
    {
        if (idx == -1)  idx = [self count];
        [self swizzled_setObject:obj atIndexedSubscript:idx];  // go use the old method: not a typo!
    }
    
    @end
    
    int main()
    {
        int x = 0, y = 1;
        NSMutableArray *fib = [NSMutableArray new];
    
        for (int i=0; i < 10; ++i) {
            fib[-1] = @(x);  // wowie zowie!
            int temp = x+y;  x = y;  y = temp;
        }
        NSLog(@"%@", fib);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-08
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 2018-07-20
      相关资源
      最近更新 更多