1

当视图从其超级视图中移除时会触发什么事件?它的子视图是否收到任何消息?例如,我将 subview2 和 subview3 添加到 subview1 中

super_view -> subview1 -> subview2 -> subview3

如果我删除 subview1 例如

[subview1 removeFromSuperview]; 

它的子视图(subview2 和 subview3)收到什么事件?

有没有办法让子视图知道他们的超级视图被删除了?

4

4 回答 4

5

这取决于 subview2 和 subview3 的保留计数。如果您通过 [[UIView alloc] initWithFrame:frame] 创建它们,然后将它们添加为子视图,它们的保留计数将为 2。(或 3,如果您在保留属性中保留引用,即 self.subview2 = [[...

因此,如果您希望在释放 subview1 时释放它们,请确保在将它们添加为子视图后再次发布它们,以便它们的保留计数只是作为子视图添加的单个计数。像这样的东西...

UIView* subview2 = [[UIView alloc] initWithFrame:myFrame];
[subview1 addSubview:subview2];
[subview2 release];
于 2009-06-25T05:02:08.810 回答
1

由于这个问题仍然悬而未决,这里有一个答案:

@implementation MySubview
- (void)willMoveToSuperview:(UIView *)newSuperview {
  if (!newSuperview) {
    // I'm being removed from my superview.
  }
}
- (void)didMoveToSuperview {
  if (!self.superview) {
    // I no longer have a superview.
  }
}
@end

如果您需要相反的情况,这是通知超级视图其子视图正在停止的方式。

@implemenation MySuperview
- (void)willRemoveSubview:(UIView *)subview {
  // I'm about to remove this view.
}
@end

它的子视图(subview2 和 subview3)收到什么事件?收到通知,
subview1但需要传递该消息(这不是自动完成的)。subview2subview3subview1

有没有办法让子视图知道他们的超级视图被删除了?
您可以制作一个简单的委托协议,也可以UIView为此目的进行扩展。

@implementation UIView (superview_notification)
- (void)notifyMyChildrenAboutTheSuperviewChange {
  [[self subviews] makeObjectsPerformSelector:@selector(notifyMyChildrenAboutTheSuperviewChange)];
}
@end

但是请记住,如果您真的想知道它们何时不再出现在屏幕上(并且它们没有超级视图这一事实是您的目标的次要),所有子视图都会通过UIWindow上述方法的镜像通知。

@implementation MySubview
- (void)willMoveToWindow:(UIWindow *)newWindow {
  if (!newWindow) {
    // I'm being removed from the screen.
  }
}
- (void)didMoveToWindow {
  if (!self.window) {
    // I'm offscreen.
  }
}
@end
于 2015-08-27T18:34:56.040 回答
0

当一个视图从它的父视图中移除时,它的所有子视图也会被移除,从而导致retaincout 减一。

看下面的代码片段:

randomImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"oldbg.png"]];
randomImage.frame = CGRectMake(10, 10, 20, 20);

aview = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 200)];

NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);

[aview addSubview:randomImage];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);
[randomImage release];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);


[self.view addSubview:aview];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);
[aview release];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);

[aview removeFromSuperview];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);

控制台日志是这样的:

 2009-08-09 23:29:42.512 ActionSheetTest[744:20b] aview retain=1,image retain=1
2009-08-09 23:29:42.513 ActionSheetTest[744:20b] aview retain=1,image retain=2
2009-08-09 23:29:42.515 ActionSheetTest[744:20b] aview retain=1,image retain=1
2009-08-09 23:29:42.516 ActionSheetTest[744:20b] aview retain=2,image retain=1
2009-08-09 23:29:42.517 ActionSheetTest[744:20b] aview retain=1,image retain=1

实际上在最后一个 NSLog 应用程序将崩溃,因为这两个对象都具有 retainCount =0。

希望这可以帮助。

于 2009-08-09T16:33:46.960 回答
0

我不认为 subviews(2,3) 在 subview1 本身被删除时会收到任何事件(至少文档中没有提到任何内容)。

编辑

多想一下……我相信当 subview1 被释放时,子视图(2,3)本身不会收到事件。

但是,如果 subview1 没有保留在其他地方,则作为 subview1 被释放的副作用,它的引用计数将达到 0 并且它将被释放。在释放期间 subview1 将释放其所有子视图。

在那种情况下,他们会被释放,我不确定这是否是你所追求的。

见简的回答。

于 2009-06-24T15:27:09.133 回答