EXC_BAD_ACCESS与IBACTION

时间:2010-01-15 08:06:11

标签: iphone uibutton exc-bad-access

我已经阅读了很多关于这个问题的内容,但我似乎仍然有所不同。 所以根据我的理解,EXC_BAD_ACCESS会出现内存管理问题。

事情是,我的似乎不是(!:))。问题是,我简单地在IB中添加了一个按钮,圆角矩形,没有图像。我把它与我班上定义的IBACTION联系在一起。顺便说一句,这个方法什么也没做(!)。

无论如何,只要我点击该按钮,应用就会崩溃,并显示“EXC_BAD_ACCESS”。

就我所知,我肯定不会过度释放任何东西。有什么问题?

任何线索?

这是我的控制台日志:

Loading program into debugger…
sharedlibrary apply-load-rules all
Program loaded.
target remote-mobile /tmp/.XcodeGDBRemote-148-79
Switching to remote-macosx protocol
mem 0x1000 0x3fffffff cache
mem 0x40000000 0xffffffff none
mem 0x00000000 0x0fff none
run
Running…
[Switching to thread 11779]
[Switching to thread 11779]
(gdb) continue
2010-01-15 09:16:34.800 FlightControl1[1899:207] Table loaded
2010-01-15 09:16:35.200 FlightControl1[1899:207] 23
2010-01-15 09:16:35.350 FlightControl1[1899:207] debug
Program received signal:  “EXC_BAD_ACCESS”.
(gdb) 

这是我得到的,在我上堆后:

#0  0x31ec3ebc in objc_msgSend ()
#1  0x33605784 in -[UIApplication sendAction:to:from:forEvent:] ()
#2  0x336056ec in -[UIApplication sendAction:toTarget:fromSender:forEvent:] ()
#3  0x336056b4 in -[UIControl sendAction:to:forEvent:] ()
#4  0x3360530c in -[UIControl(Internal) _sendActionsForEvents:withEvent:] ()
#5  0x33605f8c in -[UIControl touchesEnded:withEvent:] ()
#6  0x335fd9ac in _UIGestureRecognizerUpdateObserver ()
#7  0x30da1830 in __CFRunLoopDoObservers ()
#8  0x30de9346 in CFRunLoopRunSpecific ()
#9  0x30de8c1e in CFRunLoopRunInMode ()
#10 0x332e7374 in GSEventRunModal ()
#11 0x335adc30 in -[UIApplication _run] ()
#12 0x335ac230 in UIApplicationMain ()
#13 0x000027a8 in main (argc=1, argv=0x2ffff4d8) at /Users/SomePath/main.m:14

3 个答案:

答案 0 :(得分:53)

我也遭受了几个小时的折磨。事实证明这是一个预期的记忆问题。作为按钮目标的控制器被取消分配。它是导航控制器的根控制器,其视图直接添加到窗口中。我的代码看起来像这样:

MyController *myController = [[MyController new] autorelease];
UINavigationController* navController = 
    [[[UINavigationController alloc] initWithRootViewController:myController] autorelease];
[window addSubview:navController.view];

我的假设是myController在作为UINavigationController的根控制器传递时会被保留,但结果证明是错误的。解决方案是将控制器分配给局部变量并在dealloc中释放它。包含上述代码的对象的接口应该具有:

...
@property (retain, nonatomic) MyController *myController;
...

实施:

self.myController = [[MyController new] autorelease];
UINavigationController* navController = 
    [[[UINavigationController alloc] initWithRootViewController:myController] autorelease];
[window addSubview:navController.view];

...

- (void)dealloc {
    [self.myController release];
    ...
    [super dealloc];
}

答案 1 :(得分:4)

正如gammal和其他人指出这是一个记忆问题。它与控制器引用超出范围有关,因此其内存被释放。

如果你这样启动控制器:

MyController* controller = [[MyController alloc] initWithNibName:@"MyNib" bundle:nil];
[self.view addSubview:controller.view];

如果您不使用ARC,则可以正常使用,因为在手动释放引用之前,不会释放引用。所以我在升级项目以使用ARC时遇到了这个问题。

如果您将控制器作为自动释放启动,或者正在使用ARC,那么只要控制器存在的作用域结束,垃圾回收器就会释放控制器,按下按钮事件将导致错误的内存异常。

解决此问题的方法是使引用保持活动状态,因此在接口上声明它,或者它是否需要外部访问作为属性。

@interface MyParentController : UIView {
@private
    MyController* controller;
}

然后添加它:

controller = [[MyController alloc] initWithNibName:@"MyNib" bundle:nil];
[self.view addSubview:controller.view];

如果您确实希望以后收集内存,只需将值设置为nil。

答案 2 :(得分:0)

我有一个想法。很久以前发生在我身上。在IB中,您的View属性是否与您的视图相关联?

我曾经解开这些,而且应用程序从未启动过。

不过,更糟糕的是,再次开始这个项目。如果你到目前为止完成了2分钟的工作,那么这些头痛并不值得。

欢迎来到iPhone编程世界。 您可能很快就需要其中一个wigsmen.com; - )