說我有這樣一個數組的數組:有沒有辦法使用KVC獲取陣列數組的所有第一個對象?
NSArray *array = @[@[@1, @2], @[@3, @4], @[@5, @6]];
是否有會給我一個KVC關鍵路徑@ [@ 1,@ 3,@ 5]
說我有這樣一個數組的數組:有沒有辦法使用KVC獲取陣列數組的所有第一個對象?
NSArray *array = @[@[@1, @2], @[@3, @4], @[@5, @6]];
是否有會給我一個KVC關鍵路徑@ [@ 1,@ 3,@ 5]
令我驚訝的是,雖然它依賴於一些無證的行爲。
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
。然後外部數組將這些組合到結果數組中。
僅當對象爲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);
哪一部分沒有記錄? – Willeke
@Willeke:'NSArray'覆蓋'-valueForKey:'會專門解釋以'@'開頭的鍵。例如,'@「@ firstObject」'會在數組上調用'-firstObject'而不是轉發給元素。 –