NestedObjectSetters 1.1

NestedObjectSetters 1.1

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后一次发布2014 年 12 月

未指明的 维护。



  • Ryan Maxwell

在 NSMutableDictionary 和 NSUserDefaults 的分类中,可以通过键路径来设置嵌套对象。

目的

我经常想在一个可变的字典中设置多层深度的值。不幸的是,如果嵌套的可变字典不存在,这将失败。以下语句输出 null

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@"a"][@"b"] = @"foo";

NSLog(@"%@", dict[@"a"][@"b"]);

稍微重写这个语句可以使其更明显

[[dict objectForKey:@"a"] setObject:@"foo" forKey:@"b"];

第一个 objectForKey: 方法返回 nil,接下来的 setObject:ForKey: 会静默失败。

另一个常见的用例是当我对一个字典进行可变副本时 - 任何包含在字典中的字典仍然保持不可变,这导致了像这样的恼人、易出错的代码来简单地在除了根级别之外的地方设置新的值

NSDictionary *colorSets = @{
    @"ColorsOfTheRainbow": @{
        @"Red": @"#F00",
        @"Yellow": @"#FF0",
        @"Pink": @"#F0F",
        @"Green": @"#0F0",
        @"Purple": @"#8000FF",
        @"Orange": @"#F80"
    }
};

/* Create mutable copy of dictionary */
NSMutableDictionary *newColorSets = [colorSets mutableCopy];

/* Get second-level dictionary */
NSDictionary *currentColorsOfTheRainbow = [colorSets objectForKey:@"ColorsOfTheRainbow"];

/* Check that the second level dictionary existed. If so - create a mutable copy; if not - create a new mutable dictionary to use */
NSMutableDictionary *newColorsOfTheRainbow = (currentColorsOfTheRainbow) ? [currentColorsOfTheRainbow mutableCopy] : [NSMutableDictionary dictionary];

/* Set the value in the new dictionary */
[newColorsOfTheRainbow setObject:@"#00F" forKey:@"Blue"];

/* Set the second-level dictionary back into the mutable dictionary */
[newColorSets setObject:newColorsOfTheRainbow forKey:@"ColorsOfTheRainbow"];

分类接口

以下两个实例方法被添加到 NSMutableDictionaryNSUserDefaults

- (void)setObject:(id)object forKeyPath:(NSString *)keyPath;

- (void)setObject:(id)object
       forKeyPath:(NSString *)keyPath
createIntermediateDictionaries:(BOOL)createIntermediates
    replaceIntermediateObjects:(BOOL)replaceIntermediates;

第一个是一个方便方法,传入第二个参数的 YES - 这可能是最想要的行为。

  • createIntermediateDictionaries 在遍历键路径时创建任何必要的非存在的字典。
  • replaceIntermediateObjects 替换键路径中返回的任何非 NSDictionary 子类的对象。

上面的例子可以用以下代码简单实现

[dict setObject:@"foo" forKeyPath:@"a.b"];

[newColorSets setObject:@"#00F" forKeyPath:@"ColorsOfTheRainbow.Blue"];

分类方法前缀

方法默认以 nos_ 为前缀,以避免任何名称空间冲突。

要使用不带前缀的方法,请将 NESTEDOBJECTSETTERS_NO_PREFIX = 1 添加到项目的前缀文件,或将 NESTEDOBJECTSETTERS_NO_PREFIX=1 添加到目标的构建设置中的预处理器宏部分。

分类要求

这些分类与 ARC 和传统的保留/释放代码都兼容,并且可以在所有版本的 iOS 和 OS X 上使用。

项目要求

  • 此 Xcode 项目使用 XCTest 框架,因此需要 >= Xcode 5

用法

  • 手动安装:将 NestedObjectSetters.h/m 添加到您的项目中。
  • Cocoapods:pod 'NestedObjectSetters'