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

zpa*_*ack 6 iphone macos cocoa nsview uiview

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

NSArray* subViews = self.subviews;
for( UIView *aView in subViews ) {
    [aView removeFromSuperview];
}
Run Code Online (Sandbox Code Playgroud)

这很好用.事实上,在Mac OS X应用程序(来自NSView子类)中尝试几乎相同的东西之前,我从未真正考虑过它:

NSArray* subViews = [self subviews];
for( NSView *aView in subViews ) {
    [aView removeFromSuperview];
}
Run Code Online (Sandbox Code Playgroud)

这完全不起作用.具体来说,在运行时,我得到这个:

*** Collection <NSCFArray: 0x1005208a0> was mutated while being enumerated.
Run Code Online (Sandbox Code Playgroud)

我最终这样做了:

NSArray* subViews = [[self subviews] copy];
for( NSView *aView in subViews ) {
    [aView removeFromSuperview];
}
[subViews release];
Run Code Online (Sandbox Code Playgroud)

没关系.然而,令我烦恼的是,为什么它适用于iPhone呢?

子视图是一个复制属性:

@property(nonatomic,readonly,copy) NSArray *subviews;
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是,当指定copy属性时,@ synthesize'd getters可能会返回一个副本. doc对于setter的复制语义很清楚,但似乎没有对getter说出任何一种方式(或者至少对我来说不明显).实际上,做了我自己的一些测试,这显然不是这种情况.哪个好,我认为返回副本会有问题,原因有几个.

所以问题是:上面的代码如何在iPhone上运行?NSView显然返回了一个指向实际子视图数组的指针,也许UIView不是.也许它只是UIView的一个实现细节,我不应该对此进行研究.

有人可以提供任何见解吗?

Mik*_*lah 13

这是一个错误-[NSView subviews].我本可以发誓这是针对Snow Leopard的,但现在找不到任何证据.

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

[self setSubviews:[NSArray array]];
Run Code Online (Sandbox Code Playgroud)

  • 这几乎不是@Mike的错误.它只是[someNSView子视图]返回指向子视图数组的指针,而[someUIView subviews]返回该数组的副本.这就是它在iOS上运行良好的原因. (3认同)