2012-10-15 11 views
6

PHP有推對象到陣列的端部。使用新文本語法

是否有新的Objective-C的文字語法的這個任何等效?我能想到這樣做的最簡潔的方式是:

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

但也許有更好的東西在那裏?

回答

7

看看the documentation for the new literal syntax。當您使用標分配到一個數組,呼叫被翻譯成setObject:atIndexedSubscript:方法調用:

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

如果你有自己的可變數組的實現,你可以一個特殊的情況下添加到setObject:atIndexedSubscript:方法生長數組分配過去的數組大小時。 我非常懷疑默認 NSMutableArray實現做這樣的事情,很可能你只希望得到有關指數是出界的一個例外。 而這確實是NSMutableArray呢,看到the reference documentation

如果該指數等於計數的元素添加到 陣列結束,越來越多的陣列。

謝謝馬丁擡頭!

+3

的'NSMutableArray'文檔'的setObject:atIndexedSubscript:'明確地規定:「如果索引等於'count'的元素被添加到該陣列的端部,生長在陣列」 –

0

其實我並不推薦這樣做,但Objective-C的使人們有可能用自己的代碼擴展setObject:atIndexedSubscript:方法。這個過程被稱爲「法混寫」,它是在這裏解釋:http://darkdust.net/writings/objective-c/method-swizzling

以下是一個演示過程中的一些實際工作的代碼。涼爽位在main(),在那裏我能使用fib[-1] = ...而不是fib[fib.count] = ...。當然,這裏沒有太大的優勢。代碼沒有效率,而且閱讀起來肯定比較困難。但我確實不必寫兩次「fib」。

這種方法的主要缺點是Objective-C中確實沒有關於哪些類別加載順序的規則,因此,如果別人提供具有類似功能的類別,這將是一個toss-最後一個加載哪個。 (如果他們碰巧選擇了相同的他們的類別,這將是其中一個得到所有加載的勝負難料,我想。)

因此,底線,不這樣做。但它可能是

#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; 
}