当 addSubview 和 release 在添加的视图中无法正常工作时
Posted
技术标签:
【中文标题】当 addSubview 和 release 在添加的视图中无法正常工作时【英文标题】:When addSubview and release not working properly in added view 【发布时间】:2013-06-17 10:22:42 【问题描述】:我创建了类,它使用非弧项目添加到当前视图。之后我将它作为这个发布。
TestViewController *tView=[[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
tView.view.frame=CGRectMake(10, 10,tView.view.frame.size.width , tView.view.frame.size.height);
[self.view addSubview:tView.view];
[tView release];
我向 TestViewController 添加了按钮,当按下它时它会崩溃并从控制台查看此消息。
-[TestViewController performSelector:withObject:withObject:]: message sent to deallocated instance
谁能解释一下原因?
【问题讨论】:
显示您的按钮添加和按钮点击操作代码... 将tView.view
添加为子视图将不会保留TestViewController
实例。由于此实例在发布后收到消息,因此您的应用程序正在崩溃。将TestViewController
实例保留为ivar
并在dealloc
中释放它。
【参考方案1】:
当您调用[tView release];
TestViewController
的dealloc
方法将自动被调用。而这个类的Objects
将是released
。所以可能你已经在dealloc
中释放了那个按钮。这就是您的应用崩溃的原因。
这不是正确的做法。
您应该创建一个自定义视图并将该视图添加到self.view
,而不是添加viewcontroller
的view
。
【讨论】:
【参考方案2】:目前,您已将 TestViewController 实例声明为 local。因此,只有在访问实例中的控件时它才会崩溃。
在class level(ivar)中声明TestViewController实例,然后使用它。
【讨论】:
【参考方案3】:显然,您的按钮的目标是 tView。 [tView dealloc] 在 [tView release] 之后被调用,因为它的 retainCount 减少到 0。 您应该将 tView 声明为私有成员变量,例如 _tView,并在视图控制器的 dealloc 函数中调用 [_tView release]。
@interface **
TestViewController *_tView;
if(!_tView)
_tView=[[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
_tView.view.frame=CGRectMake(10, 10,tView.view.frame.size.width , _tView.view.frame.size.height);
[self.view addSubview:_tView.view];
在 ios 5.* 中,支持自定义容器视图控制器。 (http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html) 你可以这样写代码:
TestViewController *tView=[[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
tView.view.frame=CGRectMake(10, 10,tView.view.frame.size.width , tView.view.frame.size.height);
[self.view addSubview:tView.view];
[self addChildViewController:tView];
[tView didMoveToParentViewController:self];
[tView release];
【讨论】:
【参考方案4】:你可以使用下面的代码
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:@selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:@"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.yourViewController addSubview:button];
self.viewController 意味着您已经在 .h 文件中定义了您的视图控制器,然后使用您的视图控制器实例来添加您的按钮。
然后你可以释放你的viewController [ViewController Release];
【讨论】:
只能为 UIView 添加Subview。 UIViewController 没有这个方法。 [self.yourViewController addSubview:button];那为什么还能释放viewController呢? [yourViewController.view addSubview:button];是正确的语法。以上是关于当 addSubview 和 release 在添加的视图中无法正常工作时的主要内容,如果未能解决你的问题,请参考以下文章
viewDidLoad() 中的 addSubView() 和 bringSubViewToFront() 不起作用
发生 IBAction 时,Swift addsubview 和应用程序崩溃