7

PHP 有:

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

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

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

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

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

4

2 回答 2

7

查看新文字语法的文档。当您使用下标分配给数组时,调用将转换为setObject:atIndexedSubscript:方法调用:

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

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

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

谢谢马丁的提醒!

于 2012-10-15T07:21:08.717 回答
0

我实际上不建议这样做,但 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;
}
于 2012-10-26T19:46:45.633 回答