Objective c 使用新的文字语法将对象推送到数组末尾

Objective c 使用新的文字语法将对象推送到数组末尾,objective-c,nsmutablearray,objective-c-literals,Objective C,Nsmutablearray,Objective C Literals,PHP有: arr[] = 'Push this onto my array'; 将字符串添加到数组末尾的位置 在新的Objective-C文本语法中是否有类似的语法?我能想到的最简洁的方法是: arr[arr.count] = @"Add me"; 但也许有更好的方法呢?看看。当使用下标向数组赋值时,调用将转换为setObject:atIndexedSubscript:方法调用: NSMutableArray *foo = …; foo[0] = @"bar"; // => [foo

PHP有:

arr[] = 'Push this onto my array';
将字符串添加到数组末尾的位置

在新的Objective-C文本语法中是否有类似的语法?我能想到的最简洁的方法是:

arr[arr.count] = @"Add me";
但也许有更好的方法呢?

看看。当使用下标向数组赋值时,调用将转换为
setObject:atIndexedSubscript:
方法调用:

NSMutableArray *foo = …;
foo[0] = @"bar"; // => [foo setObject:@"bar" atIndexedSubscript:0];
如果您有自己的可变数组实现,那么可以在
setObject:atIndexedSubscript:
方法中添加一个特殊情况,以便在分配超过数组大小时增加数组。我非常怀疑默认的
NSMutableArray
实现是否有类似的功能,很可能您只是得到一个关于索引超出范围的异常。这确实是
NSMutableArray
所做的,请参见:

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


马丁,谢谢你提醒我

我实际上不建议这样做,但是Objective-C确实可以使用您自己的代码扩展
setObject:atIndexedSubscript:
方法。该过程称为“方法swizzling”,如下所述:

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

这种方法的一个主要缺点是Objective-C实际上没有任何关于类别加载顺序的规则,因此如果其他人提供了具有类似功能的类别,那么最后加载哪个类别将是一个难题。(我认为,如果他们碰巧为自己的类别选择了相同的名称,那么到底是哪一个被加载了就很难了。)

所以,底线是,不要这样做:但这是可能的

#导入
#进口
@接口NSMutableArray(NegativeOne)
+(空)荷载;
-(void)swizzled_setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
@结束
@实现NSMutableArray(NegativeOne)
+(空)荷载
{
方法original=class_getInstanceMethod(self,@selector(setObject:atIndexedSubscript:);
方法swizzled=class_getInstanceMethod(self,@selector(swizzled_setObject:atIndexedSubscript:);
方法交换实施文件(原件,SWIZED);
}
-(void)swizzled_setObject:(id)obj atIndexedSubscript:(NSUInteger)idx
{
如果(idx==-1)idx=[自计数];
[self-swizzled_setObject:obj atIndexedSubscript:idx];//使用旧方法:不要输入错误!
}
@结束
int main()
{
int x=0,y=1;
NSMUTABLEARRY*fib=[NSMUTABLEARRY new];
对于(int i=0;i<10;++i){
fib[-1]=@(x);//wowie-zowie!
int temp=x+y;x=y;y=temp;
}
NSLog(@“%@”,fib);
返回0;
}

setObject:atIndexedSubscript:的
NSMutableArray
文档明确指出:“如果索引等于
count
则将元素添加到数组的末尾,增加数组。”
#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;
}