Iphone 使用IBACTION执行错误访问

Iphone 使用IBACTION执行错误访问,iphone,uibutton,exc-bad-access,Iphone,Uibutton,Exc Bad Access,我已经读了很多关于这个问题的书,但我的书似乎还是有些不同。 所以据我所知,EXC_BAD_访问会出现内存管理问题 问题是,我的似乎不在那里。问题是,我简单地在IB中添加了一个按钮,圆角矩形,没有图像。我将它与我在类中定义的iAction连接起来。顺便说一下,这个方法不起任何作用 无论如何,只要我点击按钮,应用程序就会崩溃,出现“EXC_BAD_ACCESS” 就我所能看到的而言,我肯定没有过分夸大任何事情。怎么了 有什么线索吗 这是我的控制台日志: Loading program into de

我已经读了很多关于这个问题的书,但我的书似乎还是有些不同。 所以据我所知,EXC_BAD_访问会出现内存管理问题

问题是,我的似乎不在那里。问题是,我简单地在IB中添加了一个按钮,圆角矩形,没有图像。我将它与我在类中定义的iAction连接起来。顺便说一下,这个方法不起任何作用

无论如何,只要我点击按钮,应用程序就会崩溃,出现“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

我有一个想法。那件事很久以前就发生在我身上了。在IB中,视图属性是否连接到视图

我曾经摘下这些,但应用程序从未启动过

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

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

我也被这折磨了几个小时。果然是内存问题。作为按钮目标的控制器已解除分配。它是导航控制器的根控制器,其视图直接添加到窗口中。我的代码如下所示:

MyController *myController = [[MyController new] autorelease];
UINavigationController* navController = 
    [[[UINavigationController alloc] initWithRootViewController:myController] autorelease];
[window addSubview:navController.view];
MyController* controller = [[MyController alloc] initWithNibName:@"MyNib" bundle:nil];
[self.view addSubview:controller.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];
}

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

如果您像这样启动控制器:

MyController *myController = [[MyController new] autorelease];
UINavigationController* navController = 
    [[[UINavigationController alloc] initWithRootViewController:myController] autorelease];
[window addSubview:navController.view];
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。

您可以粘贴到控制台日志中吗?请注意,iAction本身只是IB用于查找项目的占位符。看看预处理后的代码,iBaction是不存在的。我在问题中添加了我的控制台日志@凯文:老实说,我不知道该怎么做。很可能在你点击按钮之前,执行按钮动作的对象已经被释放了。您可以尝试在其-dealoc和按钮操作方法中添加一个NSLog调用来验证它。此外,为objc_异常_throw和-[[u NSZombie methodSignatureForSelector:]启用断点(以及启用NSZombies)也会有所帮助。@在(gdb)提示符下,输入“back”命令。这将显示错误发生之前发生的情况。这是确定错误发生位置的简单第一步。谢谢!initWithRootViewController不保留根视图是疯狂的。您是在分配导航控制器之后才显示它的吗?我在使用ARC时也遇到了这个问题。问题是我一直在从方法变量实例化视图控制器。只需将其设置为实例变量或属性。调试器显示initWithRootViewController保留了控制器两次。同上,救命!我正在使用ARC当我看到这篇文章并意识到发生了什么时,我在类中添加了一个带断点的-(void)dealloc,在类中添加了我的按钮,我可以准确地看到发布的调用位置。