为什么这个对象在ARC下过早解除分配?

时间:2012-02-28 18:47:54

标签: ios uiscrollview uibutton automatic-ref-counting

我在设置UIButton的目标时遇到问题:

//  TestViewController.m
@implementation TestViewController

@synthesize scrollContentView

- (void)viewDidLoad
{
    [super viewDidLoad];
 SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

[self.scrollContentView addSubview:secondViewController.view];
}

@end

// SecondViewController.m
- (void)viewDidLoad
{
    [super viewDidLoad];
    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button1 addTarget:self action:@selector(button1Click:) forControlEvents:UIControlEventTouchUpInside];
    button1.frame = CGRectMake(20, 45, 280, 40);
    [self.view addSubview:button1];
}

- (IBAction)button1Click:(id)sender
{
    NSLog(@"test");
}

问题是,当我点击按钮时,我收到以下错误消息:

  

[SecondViewController performSelector:withObject:withObject:]:message   发送到解除分配的实例0x685c050

     

(LLDB)

我假设问题是我只是将视图传递到UIScrollView而我无法访问控制器。

知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

消息“message sent to deallocated instance”表示当变量超出secondViewController末尾的范围时,您的viewDidLoad变量未被保留 但它的视图,包含它的按钮,是。通过指向死对象的指针指向活动对象。因此你的崩溃。

由于您正在使用ARC,因此最快(可能是hackie)的方法是在SecondViewController的ivar中生成TestViewController

@implementation TestViewController{
    SecondViewController *secondViewController; // with ARC ivars are strong by default
}

然后将viewDidLoad中的行更改为:

secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

但我相信正确的方法(当然我不知道你的应用程序的细节)可能会使用:

- (void)addChildViewController:(UIViewController *)childController __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);

如果这是iPhone / iPod touch应用程序,请注意; Apple已经表示,对于这些设备,该比率通常应该是一个视图控制器到一个内容屏幕。我再也不知道你的应用程序的具体细节,只是想提一下。