【问题标题】:How to remove <null>'s from NSDictionary?如何从 NSDictionary 中删除 <null> 的?
【发布时间】:2012-11-17 09:03:19
【问题描述】:

我正在尝试使用不允许空值的 NSDictionaries 的 NSArray 的 writeToFile 方法。我想只是循环并找到它们并用空的NSString 替换,但我无法让它工作。这就是我正在尝试的。

编辑:NSArrays 和 NSDictionaries 由 NSJSONSerialization 创建。

for (NSMutableDictionary *mainDict in mainArray)
{
    for(NSMutableDictionary *subDict in mainDict)
    {
        for(NSString *key in subDict)
        {                
            id value = [subDict objectForKey:key];

            if (value == [NSNull null])
            {
                [subDict setObject:@"" forKey:key];
            }
        }
    }
}

但这会引发异常。 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

但正如您所见,所有 NSDictionaries 都是可变的。

怎么了? 有没有更好的方法来做到这一点?

编辑:将新版本移至单独的答案。

【问题讨论】:

    标签: objective-c nsdictionary nsnull


    【解决方案1】:

    你怎么知道字典是可变的?看起来他们不是。在枚举期间将它们键入为NSMutableDictionary 不会使它们可变。您可以遍历字典并将键移动到一个新的、可变的中,过滤空值。

    另外,如果您的字典来自NSJSONSerialization,请查看NSJSONReadingOptions,可以选择使用可变容器来实现反序列化结构。这并不总是一个好的解决方案,但值得一试。

    至于在枚举字典时对其进行变异:您不能更改键,因为这很容易导致枚举代码出错。但我不明白为什么你不能改变键值,这就是你所追求的。此代码有效:

    NSMutableDictionary *dict = [@{@"foo" : @"bar"} mutableCopy];
    for (NSString *key in dict) {
        dict[key] = @"baz";
    }
    

    【讨论】:

    • 另外,在枚举时改变字典是错误并引发异常。
    • 是的.....我建议创建一个单独的 NSDictionary 并将其设置为他在枚举后枚举的字典
    • 好的,谢谢。很难知道树的结构,因为它是由 NSJSONSerialization 创建的。我创建了一个带有可变副本的新版本。我是在正确的轨道上还是错过了重点?
    • 好吧,因为 H2CO3 指出了什么,这不起作用。我不太明白为什么不允许这样做,但正确的方法是什么?
    • 我已经扩展了答案(太多文字无法放入评论),希望对您有所帮助。
    【解决方案2】:

    或者重建整棵树。

    NSMutableArray *newMainArray = [[NSMutableArray alloc] init];
    for (NSArray *subArray in self.mainArray)
    {
        NSMutableArray *newSubArray = [[NSMutableArray alloc] init];
        for(NSDictionary *dict in subArray)
        {
            NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
            for(NSString *key in dict)
            {              
                id value = [dict objectForKey:key];
                if (value == [NSNull null])
                {
                    [newDict setObject:@"" forKey:key];
                } else {
                    [newDict setObject:value forKey:key];
                }
            }
            [newSubArray addObject:newdict];
            [newDict release];
        }
        [newMainArray addObject:newSubArray];
        [newSubArray release];
    }
    [self.mainArray release];     <----  ????
    self.mainArray = newMainArray;
    

    【讨论】:

    • 这段代码还有一个问题。如果我在将 self.mainArray 指向 newMainArray 之前释放它,则会引发异常。该属性定义为“@property (nonatomic, retain) NSMutableArray *mainArray;”。我可以不先释放就重新分配它吗?
    猜你喜欢
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    相关资源
    最近更新 更多