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