从超级视图中删除视图时会触发什么事件?其子视图是否收到任何消息? 例如,我将subview2和subview3添加到subview1,如
super_view - > subview1 - > subview2 - > subview3
如果我删除了subview1,例如由
[subview1 removeFromSuperview];
它的子视图(subview2和subview3)接收什么事件?
有没有办法让子视图知道他们的超级视图已删除?
答案 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)接收什么事件?
系统会通知subview1
,subview2
和subview3
需要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.。
希望这有帮助。