【问题标题】:What's safe to assume about the NSMutableArray / NSArray class cluster?关于 NSMutableArray / NSArray 类集群的安全假设是什么?
【发布时间】:2010-04-05 19:04:38
【问题描述】:

我知道您不应该使用它来决定是否更改数组:

if ([possiblyMutable isKindOfClass:[NSMutableArray class]])

但是假设我正在编写一个方法并且需要返回NSMutableArrayNSArray,这取决于possiblyMutable 的可变性。使用我的方法的类已经知道更改返回的数组是否可以接受。更改返回的数组是否可以接受直接与是否可以更改possiblyMutable 相关。

在那种特定情况下,这段代码安全吗?在我看来,如果可以接受更改数组,但我们不小心得到了一个可变数组,那没关系,因为使用我的方法的类不会尝试更改它。如果更改数组可以接受的,那么我们将总是possiblyMutable 设为NSMutableArray(尽管这是我不完全清楚的部分)。

那么……安全与否?替代品?

【问题讨论】:

  • 如果你真的需要一个可变数组,为什么不使用-mutableCopy

标签: objective-c cocoa abstract-class nsmutablearray nsarray


【解决方案1】:

没有。一点都不安全。

如果你这样做:

NSMutableArray * ma = [NSMutableArray arrayWithObject:@"foo"];
NSArray * aa = [NSArray arrayWithObject:@"foo"];

NSLog(@"Mutable: %@", [ma className]);
NSLog(@"Normal: %@", [aa className]);

然后你得到:

2010-04-05 13:17:26.928 EmptyFoundation[55496:a0f] 可变:NSCFArray
2010-04-05 13:17:26.956 EmptyFoundation[55496:a0f] 正常:NSCFArray

你也做不到:

NSLog(@"Mutable add: %d", [ma respondsToSelector:@selector(addObject:)]);
NSLog(@"Normal add: %d", [aa respondsToSelector:@selector(addObject:)]);

因为这个日志:

2010-04-05 13:18:35.351 EmptyFoundation[55525:a0f] 可变添加:1
2010-04-05 13:18:35.351 EmptyFoundation[55525:a0f] 正常添加:1

保证你有一个可变数组的唯一方法是获取现有数组的-mutableCopy,或者如果函数/方法的返回类型保证数组是可变的。

【讨论】:

  • 更明确地说,不应该有区别对待可变数组和普通数组的情况。为此,您必须从创建数组的那一刻起专门传递有关数组可变性的信息,这是一个脆弱的设计噩梦。否则,您应该始终根据需要复制或可变复制数组。
  • 那么 NSCoding 是如何工作的呢?假设我有一个可变数组数组,我对其进行编码。解码后,我是否需要遍历数组并将mutableCopy 发送到每个子数组?
  • 不,NSCFArray 在内部跟踪其自身的可变性(作为私有实现细节)。 NSCoding 会做正确的事,因为 NSCFArray 可以定义自己的编码和解码。
  • 双 +1。您应该永远需要以这种方式设计代码。如果您想要/需要可变副本,请制作 mutableCopy。在这种情况下,您可能必须向调用者返回一个新数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 2016-12-13
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
相关资源
最近更新 更多