当 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]; TestViewControllerdealloc 方法将自动被调用。而这个类的Objects 将是released。所以可能你已经在dealloc 中释放了那个按钮。这就是您的应用崩溃的原因。

这不是正确的做法。 您应该创建一个自定义视图并将该视图添加到self.view,而不是添加viewcontrollerview

【讨论】:

【参考方案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() 不起作用

addSubview 不显示工具栏顶部和底部

发生 IBAction 时,Swift addsubview 和应用程序崩溃

addSubview 将我的视图变为默认视图

iOS开发 addSubview 和 insertSubView 的区别

sql 语句 在查询的结果中在添加一列类型