UIButton触及IBAction导致EXC_BAD_ACCESS与ARC

RLH*_*RLH 4 debugging exc-bad-access objective-c ios

StackOverflow上有一些问题,用户遇到了与我相同的问题.但是,他们的解决方案都不适合我的情况.(见这里,这里,这里这里有一些我读过的SO问题但是没有找到帮助.)

在我的情况下,我有一个NIB,有一对UIButtons,与相关的控制器视图.该视图对我的项目来说相对较老,直到今天我才能毫无困难地使用这些按钮.在进行了一些与按钮行为无关的代码更改之后,我遇到了一个错误,该错误导致应用程序崩溃,破坏了该main()函数的代码,并EXC_BAD_ACCESS在我触摸View上的任何按钮时给出了错误消息.

这种情况如何或为何会发生?我实际上已经注释掉了几乎所有的功能代码,尤其是我今天早些时候修改过的功能代码,但仍然无法阻止错误的发生.

我的项目使用自动引用计数,我之前没有看到过这个错误.此外,我没有修改NIB,也没有修改IBAction与按钮相关联,因此我看不出会导致这种情况.停止错误的唯一方法是取消我UIButton在NIB中的s与我IBAction在Controller View头文件中定义的方法的链接.

我的用例唯一的"独特"方面是我在另一个子视图控制器中加载了该视图的一个或两个实例.加载的断开视图的实例数取决于数组中的对象数.下面是我用来实例化这些视图并将其作为另一个视图的子视图加载的代码.

//Called else where, this starts the process by creating a view that 
//will load the problematic view as a sub-view either once or twice.
- (id)initWithPrimarySystemView:(SystemViewController *)svc
{
    //First we create our parent, container view.
    self = [super initWithNibName:@"ContainerForViewInstaniatedFromArrayObjs" bundle:nil];
    if (self) 
    {
        //Assign parent DataModel to local instance
        [self setDataModel:((DataModelClass*)svc.DataModel)];
        for (AnotherModel* d in DataModel.ArrayOfAnotherModels)
        {
            //Instantiate the SubViewController.
            SubViewController* subsvc = [[SubViewController alloc] 
                                            initWithNibName:@"Subview" 
                                          bundle:nil 
                                          subviewPosition:d.Position ];

            //Add the SubViewControllers view to this view.
            [subsvc.view setFrame:CGRectMake((d.Position-1)*315, 0, 315, 400)];
            [self.view addSubview:subsvc.view];
        }
        [self setDefaultFrame: CGRectMake(0, 0, 640, 400)];
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

这完美地工作,以前,甚至没有引起关联视图上的按钮的任何问题,但是,现在所有UIButton的应用程序在点击时崩溃.

SubViewController的初始化函数以及该viewDidLoad方法除了在创建新的ViewController时添加的标准自动生成代码之外什么都不包含.

我该怎么做才能修复或诊断这个问题?

icc*_*cir 8

在您的代码中查看我的评论:

{
    SubViewController* subsvc = [[SubViewController alloc] initWithNibName:@"Subview" bundle:nil subviewPosition:d.Position ];
    //!i: By default, subsvc is a __strong pointer, so your subview has a +1 retain count
    //    subsvc owns subsvc.view, so subsvc.view has a +1 retain count as well

    //Add the SubViewControllers view to this view.
    [subsvc.view setFrame:CGRectMake((d.Position-1)*315, 0, 315, 400)];

    [self.view addSubview:subsvc.view];
    //!i: This bumps subsvc.view to +2, as self.view strong-references it

    //!i: subsvc is going out of scope, so the reference count on subsvc will drop
    //    to 0 and it is dealloc'd.  subsvc.view's retain count drops to +1, as it
    //    is still referenced by self.view
    //
    //    Most likely, in -[SubViewController dealloc], you were not doing a 
    //    setTarget:nil, setAction:nil on the button.  Thus, the button now 
    //    has a dangling pointer and will crash when hit
}
Run Code Online (Sandbox Code Playgroud)

要解决此问题,请将每个SubViewController实例添加到主视图控制器拥有的阵列中.这将使SubViewController实例保持接收按钮水龙头.