24

我已经阅读了很多关于这个问题的内容,但我的似乎仍然有所不同。因此,据我了解, 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
4

3 回答 3

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];
}
于 2010-02-24T01:42:13.040 回答
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。

于 2013-03-17T01:18:34.750 回答
0

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

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

顺便说一句,更糟的是,重新开始这个项目。如果到目前为止你已经完成了 2 分钟的工作,那么这些头痛就不值得了。

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

于 2010-01-15T11:15:01.750 回答