【问题标题】:NSDictionary +dictionaryWithDictionary or -copy?NSDictionary +dictionaryWithDictionary 还是 -copy?
【发布时间】:2013-06-09 05:49:35
【问题描述】:

哪种方法被认为是从原始字典派生新字典的更好方法:

[NSDictionary dictionaryWithDictionary:otherDictionary];

[otherDictionary copy];

有时我们需要从不可变的字典中创建一个可变的字典,因此这个问题不断出现。也许没有,但我很好奇在某些用例中是否比其他。

编辑:我知道上述方法不能用于派生可变字典。我只是想笼统地问这个问题,然后解释一下我每天是如何面对这个问题的。我应该更清楚这一点。

【问题讨论】:

    标签: objective-c foundation


    【解决方案1】:

    实际上,它们不同的,但不是出于您期望的原因。我将假设您正在使用 ARC(如果您没有,为什么不呢?),所以返回对象的自动释放并不重要。

    它们的区别如下:考虑如果 otherDictionarynil 会发生什么。

    好吧,如果你使用:

    [otherDictionary copy]; // or -mutableCopy
    

    您将返回nil,因为您有一个nil 接收器。

    另一方面,如果你使用:

    [NS(Mutable)Dictionary dictionaryWithDictionary:otherDictionary];
    

    无论otherDictionary 是否为nil,您取回NS(Mutable)Dictionary

    这在您需要创建字典副本之后想要一个 NSDictionary 实例,但您不想测试 nil 的情况下很好(耶降低圈复杂度!)。

    【讨论】:

    • 先生,这是一个很好的收获。而且,为了指出选择一个而不是另一个的实际原因,你应该打勾。
    • iOS 9.0 标头将dictionaryWithDictionary: 的参数标记为(隐式)_Nonnull。这只是一个疏忽还是 Apple 表示不应依赖 nil 参数的过去行为?
    【解决方案2】:

    关于这个问题有几点:

    首先,这两者略有不同:

    [NSDictionary dictionaryWithDictionary:otherDictionary];    #1
    [otherDictionary copy];                                     #2
    

    #1 返回一个自动释放的对象(即,保留计数为 +0 的对象); #2 返回一个具有 +1 保留计数的对象,因此调用者负责在某个时候调用 release

    (如果otherDictionarynil,它们也略有不同:#1 返回一个空字典,而#2 返回nil。)

    当然,在您的问题中,您实际上询问的是 mutable 副本。请注意,您可以执行以下任一操作:

    [NSMutableDictionary dictionaryWithDictionary:otherDictionary];
    [otherDictionary mutableCopy];
    

    上述相同的注意事项适用于这些方法中的每一种。

    本身可能没有最佳方式,但mutableCopy 是最清楚的(请记住,您必须在某个时候释放保留的对象)。

    【讨论】:

    • 很好的答案。因此,对于 ARC,选择完全是一个品味问题。
    • 很好的答案,但它们并不完全相同。如果otherDictionarynil,则会出现差异。
    • @DaveDeLong:在我的回答中做了注释。
    【解决方案3】:

    它们在语义上是等价的。使用哪一个完全是一个选择问题。我赞成-copy,只是因为它更短,并且更清楚地说明了正在发生的事情。

    如果您需要一个可变副本(如您的文本所示),您发布的行将不起作用。你需要:

    [NSMutableDictionary dictionaryWithDictionary:otherDictionary];
    

    或者,等效地:

    [otherDictionary mutableCopy];
    

    在内存管理方面,-copy-mutableCopy 返回一个保留计数为 +1 的对象,这意味着您需要在使用完它们后释放它们。 -dictionaryWithDictionary: 返回一个自动释放的对象,所以当你完成它时不需要释放它,如果你想保留它就需要保留它。 在过去(ARC 之前)的日子里,这种区别意味着您使用哪种方法可能取决于您的内存管理需求(当然,在额外的保留或释放之后,它们仍然可以互换)。当然,如果您使用的是 ARC,那么这种区别对您来说无关紧要。

    【讨论】:

    • 是的,我总是使用mutableCopy(因为它不会像你说的那样工作)。我只是想以一般方式提出问题,而不是专门针对可变推导。
    【解决方案4】:

    Cocoa 认可的方式是发送一个 mutableCopy 方法,该方法返回一个可变副本:

    NSMutableDictionary *mutableOtherDictionaryCopy = [otherDictionary mutableCopy]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 2020-07-23
      相关资源
      最近更新 更多