当返回值是不可变对象时,返回可变对象是否是一种不好的实践?

3
如果我有这个方法:
+ (NSDictionary *)dictionaryFromQueryString:(NSString *)queryString
{
    NSMutableDictionary *this = [[NSMutableDictionary alloc] init];

    NSArray *fields = [queryString componentsSeparatedByString:@"&"];

    for(NSString *field in fields)
    {
        NSArray *fieldParts = [field componentsSeparatedByString:@"="];

        NSString *value = @"";

        if(fieldParts.count > 1)
        {
            value = [[fieldParts subarrayWithRange:NSMakeRange(1, fieldParts.count - 1)] componentsJoinedByString:@"="];
        }

        [this setObject:unescape(value) forKey:unescape(fieldParts[0])];
    }

    return this;
}

我返回NSMutableDictionary而不是NSDictionary,这样做是否不好?

我应该使用return [this copy];将其转换为NSDictionary吗?

3个回答

5

这要看情况。

Sergio的答案是正确的,但有一个非常重要的问题:

当包含可变字典的对象在另一个对象检索它后突变该字典会发生什么?除非那个对象特别支持字典可能会变异的潜力,否则其他对象现在将处于不一致状态。

由于copy对于字典来说很快,因为它是一个浅不可变副本,你通常最好总是返回一个副本,而不是返回对可变版本的引用。如果你发现你的代码正在频繁使用制作副本的方法,那么就在你的对象中缓存一个不可变的副本并出售它,在可变的后备存储更改时使其无效。


2

我认为这并不是一种不好的做法。这样做的净效果是,你的NSDictionary的接收者将不会尝试修改该对象(尽管该对象是可变的)。这是完全安全的,并且很有意义,因为您的消费者方法更加通用(它可以使用可变和不可变对象)。


0

以这种方式返回不可变对象并不是真正的不良实践,因为NSMutableDictionaryNSDictionary的子类。这是多态性,所以“一切都好。”

但我仍然建议像这样返回一个自动释放的副本:

return [NSDictionary dictionaryWithDictionary:this];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接