Iphone UIView.subview和[NSView子视图]之间的行为差异

Iphone UIView.subview和[NSView子视图]之间的行为差异,iphone,cocoa,macos,uiview,nsview,Iphone,Cocoa,Macos,Uiview,Nsview,我在iPhone应用程序中有一段代码,它从UIView子类中删除了所有子视图。看起来是这样的: NSArray* subViews = self.subviews; for( UIView *aView in subViews ) { [aView removeFromSuperview]; } 这个很好用。事实上,我从来没有认真考虑过这个问题,直到我在Mac OS X应用程序中尝试了几乎相同的东西(来自NSView子类): 那完全行不通。具体地说,在运行时,我得到以下结果: ***

我在iPhone应用程序中有一段代码,它从UIView子类中删除了所有子视图。看起来是这样的:

NSArray* subViews = self.subviews;
for( UIView *aView in subViews ) {
    [aView removeFromSuperview];
}
这个很好用。事实上,我从来没有认真考虑过这个问题,直到我在Mac OS X应用程序中尝试了几乎相同的东西(来自NSView子类):

那完全行不通。具体地说,在运行时,我得到以下结果:

*** Collection <NSCFArray: 0x1005208a0> was mutated while being enumerated.
那很好。然而,让我烦恼的是,为什么它能在iPhone上工作

子视图是一个副本属性:

@property(nonatomic,readonly,copy) NSArray *subviews;
我的第一个想法是,当指定copy属性时,@synthesis'd getter可能会返回一个副本。对于setter的copy的语义是清楚的,但是对于getter似乎没有说任何一种方式(或者至少,我并不清楚)。事实上,我自己做了一些测试,结果显然不是这样。这是好的,我认为返回副本会有问题,原因有几个

所以问题是:上面的代码在iPhone上是如何工作的?NSView显然返回了一个指向实际子视图数组的指针,而UIView可能不是。也许这只是UIView的一个实现细节,我不应该为此而激动


有人能提供一些见解吗?

是的,这正是苹果如何实施的。在mac上,子视图返回视图使用的实际(可变)数组,因此在添加或删除视图时不能使用快速枚举。如果要使用reverseObjectEnumerator,您可以。不要使用普通枚举数,因为它可能会在子视图上移以替换已删除的子视图时跳过这些子视图。然而,在iOS中,苹果似乎已经意识到了这个问题,并通过自动返回一份拷贝来修复它。属性声明只描述了它是如何设置的,但苹果也选择了复制作为getter。

更好地使用它

while([self.subviews count] > 0){
    [[self.subviews objectAtindex:0] removeFromSuperview];
}

希望有帮助。

这是
-[NSView子视图]
中的一个错误。我可以发誓它是为雪豹修好的,但现在找不到任何证据

幸运的是,有一种更简单的方法可以删除所有子视图:

[self setSubviews:[NSArray array]];

这只不过是一只虫子@迈克。只是[SomenView Subview]返回指向子视图数组的指针,而[someUIView Subview]返回该数组的副本。这就是它在iOS上运行良好的原因。
while([self.subviews count] > 0){
    [[self.subviews objectAtindex:0] removeFromSuperview];
}
[self setSubviews:[NSArray array]];