我有一个简单的应用程序,只有一个视图,上面有一个按钮。单击按钮时,它会添加第二个视图。第二个视图有一个简单的工具栏,上面有一个UIBarButtonItem
。它被注册以触发我的视图控制器的消息。
但是只要我点击该按钮,应用程序就会崩溃。启用Zombies,我看到我的视图控制器被解雇了。通过调用dealloc
添加NSLog()
函数,我看到只要我的视图可见,我的视图控制器就会被解除!
也不会触发shouldAutorotateToInterfaceOrientation
之类的消息。
我的ViewController .h:
#import <UIKit/UIKit.h>
@interface IssueViewController : UIViewController
{
IBOutlet UIBarButtonItem *button;
}
@property (nonatomic, readonly) UIBarButtonItem *button;
- (IBAction)buttonTapped:(id)sender;
+ (void)showSelfInView:(UIView *)view;
@end
其.m:
#import "IssueViewController.h"
@interface IssueViewController ()
@end
@implementation IssueViewController
@synthesize button;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.button.target = self;
self.button.action = @selector(buttonTapped:);
}
- (void)viewDidUnload
{
NSLog(@"unloaded");
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc
{
NSLog(@"Got dealloc");
}
+ (void)showSelfInView:(UIView *)view
{
IssueViewController *ivc = [[IssueViewController alloc] init];
[view addSubview:ivc.view];
}
- (IBAction)buttonTapped:(id)sender
{
[self.view removeFromSuperview];
}
@end
用于触发第二视图显示的代码:
[IssueViewController showSelfInView:self.view];
任何人都知道我做错了什么?为什么我的UIViewController
至少在视图被移除之前才会被保留?
修改
我知道ARC,强大和优秀;弱引用...在非ARC代码中,在showSelfInView
中:我将保留视图控制器,我将在buttonTapped
中自动发布它。
对我来说,这是实现这一目标的好方法。而且我想知道我是否遗漏了ARC的某些内容,或者我使用view / viewController的方式。由于视图仍然可见,对我来说,它的viewController不应该被解除分类。除了创建我自己对视图控制器的强引用之外,还有什么方法可以阻止它吗?
改写
在视图从显示中删除之前,是否存在任何非零的非脏方式让视图控制器保持分配状态。我认为从视图控制器到自身的任何指针都是脏的,尽管这是我目前使用的方式。
答案 0 :(得分:0)
如果您不希望arc立即释放它(在定义实例的范围的末尾),您必须保持对IssueViewController实例的强引用。
答案 1 :(得分:0)
答案是:添加一个viewcontroller的视图作为另一个viewcontroller视图的子视图是一种不好的做法,应该避免使用。