2016-10-28 31 views

回答

1

令我驚訝的是,雖然它依賴於一些無證的行爲。

NSArray覆蓋-valueForKey:的文檔聲明,它通過將-valueForKey:應用於每個元素並使用提供的鍵創建一個新數組並返回該數組。它確實不是建議任何密鑰都是特殊的。

但是,NSDictionary的重寫確實表示以@開頭的關鍵字會被專門處理。它不是查看字典的內容,而是查看字典本身的屬性,其中一個匹配去掉前導@的密鑰。因此,您可以使用[someDict valueForKey:@"@count"]來獲取字典中對象的數量。

事實證明,NSArray實際上尊重相同的約定。在您的示例中,您可以使用[array valueForKey:@"@firstObject"]獲取@[@[@1, @2]]。現在的問題是,你如何應用到內部數組,而不是外部數組。

首先,如果您只需撥打[array valueForKey:@"firstObject"]而不在密鑰上的@會發生什麼?外部陣列在每個內部陣列上調用[innerArray valueForKey:@"firstObject"]。每個內部陣列依次嘗試在其每個元素上調用[element valueForKey:@"firstObject"]。但是,它的元素是NSNumber對象,它們對於「firstObject」關鍵字不符合KVC標準。所以那個爆炸了。

但是,KVC支持collection operators-valueForKeyPath:(請注意「路徑」的結尾)。一個運營商是@unionOfObjects。這將運算符右側的路徑部分應用到數組的元素,然後返回結果數組。這與-valueForKey:傳播到內部數組的情況類似,不同之處在於您需要爲內部數組指定不同的鍵。

所以,結合這些機制,你可以這樣做:[array valueForKeyPath:@"@[email protected]"]得到@[@1, @3, @5]。外部陣列將[innerArray valueForKeyPath:@"@firstObject"]應用於每個內部陣列。由於主導@,這不會傳播到內部數組的元素。它只是獲得內部陣列的firstObject。然後外部數組將這些組合到結果數組中。

+0

哪一部分沒有記錄? – Willeke

+0

@Willeke:'NSArray'覆蓋'-valueForKey:'會專門解釋以'@'開頭的鍵。例如,'@「@ firstObject」'會在數組上調用'-firstObject'而不是轉發給元素。 –

0

僅當對象爲confirming Key Value coding compliance時,KVC鍵路徑才起作用。指對象,縮放器值應該具有沿着鍵名稱的setter和getter。在你的結構中,索引路徑沒有getter和setter的鍵。所以我創建了自定義getter方法來滿足內部對象索引路徑的NSKeyValueCoding。這將適用於內部陣列的每個索引。

@interface NSArray (KVO) 
- (id) unionOfObjectsForKeyPath:(NSString*)keyPath; 
@end 

@implementation NSArray (KVO) 

- (id) unionOfObjectsForKeyPath:(NSString*)keyPath 
{ 
    NSMutableArray * values = [NSMutableArray new]; 
    for (id obj in self) { 
     if ([obj isKindOfClass:[NSArray class]]) { 

      @try { 
       NSUInteger index = [keyPath integerValue]; 
       id value = nil; 
       if (index < [(NSArray *)obj count]) { 
        value = [obj objectAtIndex:index]; 
        if(value && value!=[NSNull null]) 
        { 
        [values addObject:value]; 
        } 
       } 
      } 
      @catch (id) {} 
     } 
    } 
    return [NSArray arrayWithArray:values]; 
    } 
@end 

在VC:

self.myArray = @[@[@1, @2], @[@3, @4], @[@5, @6]]; 
NSArray *testArray =[self.myArray unionOfObjectsForKeyPath:@"0"]; 
NSLog(@"test array : %@", testArray); 
相關問題