初始化NSMutableArray:[NSMutableArray array];

7
如果您使用上述NSArray的便捷方法初始化NSMutableArray,您会得到一个NSArray还是一个NSMutableArray?
有什么后果吗?
(我知道NSMutableArray有“arrayWithCapacity:”,我只是好奇)

1
我很欣赏下面有关一个简单问题的有趣讨论。它涉及到一些微妙的Cocoa要点。 - Corey Floyd
2个回答

11

如果你使用以下方式进行初始化:

NSMutableArray *array = [NSMutableArray array];

你得到了一个NSMutableArray。Objective-C的一个伟大特点是子类可以继承父类方法。

因此,在一个类方法中,你可以这样做:

+(id)array {
    return [[[self alloc] init] autorelease];
}

self将引用执行代码的类对象(NSArrayNSMutableArray)。


啊哈,有趣。所以self引用了类对象NSMutableArray。这很有道理。我想知道为什么我的代码没有出错! - Corey Floyd
1
我认为你实际上会这样做:return [[[self alloc] init] autorelease]; - Don McCaughey

4
更新:虽然我的建议“亲自测试”通常是个好主意,但在这种情况下它可能过于草率了。感谢评论中的Jim指出我的下面的建议对于这些类并不适用,因为各种形式的NSArray都是由CoreFoundation桥接类实现的。
----- 原始回答如下 -----
回答这样的问题最简单的方法就是自己测试一下。尝试以你感到好奇的方式分配数组,然后从你的代码中使用NSLog:
NSLog(@"我们得到了一个%@", NSStringFromClass([theArray class]));

1
那肯定会返回 NSCFArray 吧? - Jim Dovey
太好了,Jim。我忘记了NSArray的那个特点。我会编辑我的上面回答的。谢谢。 - danielpunkass
嗯,有趣。所以即使是NSMutableArray也会返回NSCFArray?这使得内省变得困难,无法在尝试更改对象之前找出是否具有可变对象。我猜你可以在这种情况下使用respondsToSelector。顺便说一句,感谢您的精彩播客。我已经回去听了大部分你和曼顿过去的节目。相当有趣和富有启发性。 - Corey Floyd
是的,在那种情况下使用 respondsToSelector 似乎是一个合理的方法。也许有更好的方式来检查可变性,我不知道。很高兴听到您喜欢这个播客! - danielpunkass
很遗憾,这是不可能的。NSCFArray 实现了一组方法,并且如果它是一个可变实例,它也不会改变该列表。这都是有趣的无需桥接的内容:NSCFArray 实际上是应用于 CFArrayRef 实例的 ObjC 类描述——换句话说,创建一个 CFArrayRef,调用 [ref class],然后它将返回 NSCFArray。我知道的唯一可靠测试可变性的方法是将其包装在 try/catch 块中,并处理如果它真的不可变时引发的 NSInternalInconsistencyException。或者深入研究 CF 源代码并检查 CF 标头位 ;) - Jim Dovey
哇,我想不出有什么情况下我会真的不知道我是否在处理可变对象,但这绝对是一个很好的方法来确定可变性。这只是一种智力锻炼,但它确实揭示了一个奇怪的问题,你可能会遇到并浪费数小时的时间。 - Corey Floyd

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