从SuperView中删除视图,通知iPhone上的子视图

时间:2009-06-24 15:00:46

标签: iphone cocoa-touch uikit uiview

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

super_view - > subview1 - > subview2 - > subview3

如果我删除了subview1,例如由

[subview1 removeFromSuperview]; 

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

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

4 个答案:

答案 0 :(得分:5)

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

因此,如果您希望在发布subview1时释放它们,那么请确保在将它们添加为子视图后再给它们一个版本,这样它们的保留计数就是添加为子视图的唯一一个。像这样......

UIView* subview2 = [[UIView alloc] initWithFrame:myFrame];
[subview1 addSubview:subview2];
[subview2 release];

答案 1 :(得分: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)接收什么事件?
系统会通知subview1subview2subview3需要subview1传递该消息(这不会自动完成)。

有没有办法让子视图知道他们的超级视图被删除了?
您可以制作一个简单的委托协议,也可以为此目的扩展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

答案 2 :(得分:0)

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

修改

更多思考......我相信当subview1发布时,子视图(2,3)本身不会收到事件。

但是,如果subview1没有保留在其他地方,则subview1的副作用会被释放,其ref计数将达到0并且将被取消分配。在解除分配期间,subview1将释放其所有子视图。

在这种情况下,他们会被释放,我不确定这是不是你想要的。

见Jane的回答。

答案 3 :(得分:0)

当从其超级视图中删除视图时,其所有子视图也将从其中删除,从而导致将retaincout减少一个。

查看以下代码snipet:

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,应用程序将崩溃,因为两个objets都有retainCount = 0.。

希望这有帮助。