【问题标题】:Set the same value for all existing keys in an NSDictionary为 NSDictionary 中的所有现有键设置相同的值
【发布时间】:2017-03-08 17:12:12
【问题描述】:

在 KVC 中,我通常使用setValues:forKeyPath: 为集合中的对象设置相同的值。例如:

NSMutableArray <SomeClass *> *arr = [[NSMutableArray alloc] initWithCapacity:10];
for (int i = 0; i < 10; i++) {
    SomeClass *obj = [[SomeClass alloc] init];
    obj.stringProp = @(i).stringValue;
    [arr addObject:obj];
}

NSLog(@"- %@", [arr valueForKeyPath:@"stringProp"]);
[arr setValuesForKeysWithDictionary:@{@"stringProp" : @"Same same!"}];

NSLog(@"- %@", [arr valueForKeyPath:@"stringProp"]);
[arr setValue:@"Another" forKeyPath:@"stringProp"];

NSLog(@"- %@", [arr valueForKeyPath:@"stringProp"])

但是,对于字典,我们也可以使用它吗?现在我必须手动设置值:

NSMutableDictionary *myDict;
//... setupValues
NSString *valueToSet = @"Hehe";
for (NSString *key in myDict) {
    [myDict setObject:valueToSet forKey:key];
}

有没有像上面的例子那样简单的字典解决方案?

【问题讨论】:

    标签: objective-c cocoa nsmutabledictionary kvc


    【解决方案1】:

    我不确定是否有这样的功能(我想没有),但如果您需要多次执行此操作,您可以向 NSMutableDictionary 添加一个功能来帮助您:

    @interface NSMutableDictionary (NSMutableDictionarySetAllKeysObject)
    -(void)setAllKeysObject:(nonnull id)object;
    @end
    
    @implementation NSMutableDictionary (NSMutableDictionarySetAllKeysObject)
    -(void)setAllKeysObject:(nonnull id)object
    {
        for (NSString *key in self.allKeys) {
            [self setObject:object forKey:key];
        }
    }
    @end
    

    所以你可以这样做:

    NSString *valueToSet = @"Hehe";
    [myDict setAllKeysObject:valueToSet];
    

    【讨论】:

    • 可能他们没有这个功能(还没有?)。几天后我会接受你的回答,以防有人找到我要求的方法:p
    【解决方案2】:

    您可以先使用allValues 方法将所有值作为NSArray 获取。然后获取数组的可变副本。最后,在可变数组上使用您在问题中提到的任何 KVC 方法(setValuesForKeysWithDictionarysetValue:forKeyPath: 等...)


    根据你的例子

    [[[myDict allValues] mutableCopy] setValuesForKeysWithDictionary:@{@"stringProp" : @"Same same!"}];`
    
    [[[myDict allValues] mutableCopy] setValue:@"Another" forKeyPath:@"stringProp"];`
    

    或者实现一个类别

    @interface NSMutableDictionary (KVCForValues)
    
    - (void)setValuesForValuesWithKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
    - (void)setValue:(nullable id)value forValuesWithKeyPath:(NSString *)keyPath;
    
    @end
    
    @implementation NSMutableDictionary (KVCForValues)
    
    - (void)setValuesForValuesWithKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues {
      [[[self allValues] mutableCopy] setValuesForKeysWithDictionary:keyedValues];
    }
    
    - (void)setValue:(id)value forValuesWithKeyPath:(NSString *)keyPath {
      [[[self allValues] mutableCopy] setValue:value forKeyPath:keyPath];
    }
    
    @end
    

    并利用它

    [myDict setValuesForValuesWithKeysWithDictionary:@{@"stringProp" : @"Same same!"}];
    
    [myDict setValue:@"Another" forValuesWithKeyPath:@"stringProp"];
    

    这种方法有意义,当您想使用 KVC 方法时,接受的答案是不可能的。


    具体例子

    假设SomeClass定义如下

    @interface SomeClass: NSObject
    
    @property (nonatomic, strong) NSString *someProperty;
    @property (nonatomic, assign) NSInteger anotherProperty;
    
    @end
    
    @implementation SomeClass
    
    - (NSString *)description {
        return [NSString stringWithFormat:@"someProperty=%@, anotherProperty=%d", self.someProperty, (int)self.anotherProperty];
    }
    
    @end
    

    执行以下操作

    SomeClass *value1 = [[SomeClass alloc] init];
    value1.someProperty = @"aaa";
    value1.anotherProperty = 111;
    
    SomeClass *value2 = [[SomeClass alloc] init];
    value2.someProperty = @"bbb";
    value2.anotherProperty = 222;
    
    SomeClass *value3 = [[SomeClass alloc] init];
    value3.someProperty = @"ccc";
    value3.anotherProperty = 333;
    
    NSDictionary *someDictionary = @{@"key1": value1, @"key2": value2, @"key3": value3};
    
    NSLog(@"%@", someDictionary);
    

    将产生以下输出

    key1 = "someProperty=aaa, anotherProperty=111";
    key2 = "someProperty=bbb, anotherProperty=222";
    key3 = "someProperty=ccc, anotherProperty=333";
    

    执行后

    [[[someDictionary allValues] mutableCopy] setValue:@"SameValue" forKeyPath:@"someProperty"];
    
    NSLog(@"%@", someDictionary);
    

    输出将是

    key1 = "someProperty=SameValue, anotherProperty=111";
    key2 = "someProperty=SameValue, anotherProperty=222";
    key3 = "someProperty=SameValue, anotherProperty=333";
    

    【讨论】:

    • 看来你误解了这个问题。在我的示例(NSDictionary)中,我询问是否可以使用 KVC 在平面字典中将 VALUE 设置为 ALL KEYS。比如,一个带有键和值的字典:[0: "0", 1: "1", 2: "2", 3: "3"],我想把它变成[0: "Same", 1: "Same", 2: "Same", 3: "Same"]。这对你有意义吗?
    • @Eddie 这正是上面代码的作用。我添加了一个示例代码。在任何情况下,您评论中的 NSDictionary 值应该是您的问题中的 SomeClass 类型,而不是 NSString。即使使用NSMutableArray,它也不适用于NSString
    • 这是一个很好的解释。但是,不可能直接为键设置值,而是需要对象作为桥接并将值设置为对象的属性,对吗?就像,不可能像我之前的评论那样设置它,是吗?
    • @Eddie 不可能
    猜你喜欢
    • 2015-01-12
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    相关资源
    最近更新 更多