[英]Removing View from its SuperView, Notifying the Subviews on iPhone
從超級視圖中刪除視圖時會觸發什么事件? 它的子視圖是否收到任何消息? 例如,我將subview2和subview3添加到subview1中,如下所示:
super_view-> subview1-> subview2-> subview3
如果我刪除subview1例如
[subview1 removeFromSuperview];
它的子視圖(subview2和subview3)接收什么事件?
有沒有辦法讓子視圖知道其超級視圖已刪除?
它取決於subview2和subview3的保留計數。 如果您通過[[UIView alloc] initWithFrame:frame]創建它們,然后將它們添加為子視圖,則它們的保留計數為2。(或3,如果您將引用保留在保留的屬性中,即self.subview2 = [[...
因此,如果要在發布subview1時發布它們,請確保在將它們添加為子視圖后再給它們一個版本,以便它們的保留計數只是添加為子視圖的一個。 像這樣
UIView* subview2 = [[UIView alloc] initWithFrame:myFrame];
[subview1 addSubview:subview2];
[subview2 release];
由於此問題仍未解決,因此有一個答案:
@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
我認為subview1本身被刪除(至少在文檔中未提及)時,subviews(2,3)不會收到任何事件。
編輯 :
仔細考慮一下...我相信subviews(2,3)在釋放subview1時本身不會接收事件。
但是,如果不保留subview1,則釋放subview1的副作用是,其ref計數將達到0,並且將被釋放。 在解除分配期間,subview1將釋放其所有子視圖。
在這種情況下,它們將被釋放,我不確定這是否是您所追求的。
參見簡的答案。
當視圖從其父視圖中移除時,其所有子視圖也將從中移除,從而導致保留球減少一個。
看下面的代碼片段:
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中,應用程序將崩潰,因為這兩個對象都具有keepCount = 0。
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.