【发布时间】: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
PHP 有:
arr[] = 'Push this onto my array';
字符串将被添加到数组末尾的位置。
在新的 Objective-C 文字语法中是否有任何等价物?我能想到的最简洁的方法是:
arr[arr.count] = @"Add me";
但也许那里有更好的东西?
【问题讨论】:
标签: objective-c nsmutablearray objective-c-literals
看看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 的提醒!
【讨论】:
NSMutableArray 的 setObject:atIndexedSubscript: 文档明确指出:“如果索引等于 count,则将元素添加到数组的末尾,从而扩大数组。”
我实际上并不推荐这样做,但 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;
}
【讨论】: