UIButton 调用选择器使应用程序崩溃
Posted
技术标签:
【中文标题】UIButton 调用选择器使应用程序崩溃【英文标题】:UIButton calling selector crashes the app 【发布时间】:2012-05-04 15:56:34 【问题描述】:在我的应用程序中,我有一个按钮,它是已经在 .h 文件中声明的实例变量。 现在,在为它分配一个目标并实际按下按钮后,应用程序崩溃了,在调试器中给了我以下输出:
-[__NSCFString handleActionSheet:]: unrecognized selector sent to instance 0x9090330
2012-05-04 17:51:02.646 financeAppV2[2595:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString handleActionSheet:]: unrecognized selector sent to instance 0x9090330'
*** First throw call stack:
(0x13d1022 0x1562cd6 0x13d2cbd 0x1337ed0 0x1337cb2 0x13d2e99 0x1e14e 0x1e0e6 0xc4ade 0xc4fa7 0xc3d8a 0x2dfa1a 0x13a599e 0x133c640 0x13084c6 0x1307d84 0x1307c9b 0x12ba7d8 0x12ba88a 0x1b626 0x29dd 0x2945)
terminate called throwing an exceptionCurrent language: auto; currently objective-c
我的代码如下所示:
saveButton=[UIButton buttonWithType:UIButtonTypeCustom];
[saveButton setBackgroundImage:[UIImage imageNamed:@"intervalbutton"] forState:UIControlStateNormal];
[saveButton setBackgroundImage:[UIImage imageNamed:@"intervalbuttonpressed"] forState:UIControlStateHighlighted];
saveButton.alpha=.8;
saveButton.frame= frame;
UILabel* label=[[UILabel alloc]initWithFrame:CGRectMake(0, 2, saveButton.frame.size.width, 21)];
[saveButton addSubview:label];
[saveButton addTarget:self action:@selector(handleActionSheet:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:saveButton];
-(void)handleActionSheet:(id)sender
NSLog(@"working");
您知道为什么应用程序可能会崩溃吗?
【问题讨论】:
注释掉[saveButton addSubview:label];
还会出现这种情况吗?
是的。事实上,我什至得到一个奇怪的错误:-[_UITableViewSeparatorView handleActionSheet:]: unrecognized selector sent to instance 0x6a89a30 2012-05-04 18:12:52.485 financeAppV2[2997:f803] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因是: ' - [_ UITableViewSeparatorView handleActionSheet:]:无法识别的选择发送到实例0x6a89a30' ***第一掷调用堆栈:(0x13d1022 0x1562cd6 0x13d2cbd 0x1337ed0 0x1337cb2 0x13d2e99 0x1e14e 0x1e0e6 0xc4ade 0xc4fa7 0xc3d8a 0x2dfa1a 0x13a599e 0x133c640 0x13084c6 0x1307d84 0x1307c9b 0x12ba7d8 0x12ba88a为0x1 ...
【参考方案1】:
如果不查看您的其余代码,很难具体说明,但 self
未正确保留。
您正确设置了按钮(据我所知)并将目标指向self
。不幸的是,当您按下按钮时,self
已经超出范围,NSString
使用了相同的内存。当您向handleActionSheet:
消息发送字符串时,ios 会感到惊讶。
【讨论】:
什么表明self
没有正确保留?也可能是其他几件事,对吧?
谢谢斯蒂芬!通过您的指导,我实际上发现了问题所在。放置我的按钮的视图控制器不是实例变量。这就是为什么我认为 ARC 发布得太早了。我为该视图控制器创建了一个属性,然后它就起作用了!非常感谢!【参考方案2】:
您正在向__NSCFString
对象(可能是NSString
)发送一条名为initAllIVars:
的消息。
搜索该消息并尝试找出为什么接收该消息的对象是NSString
。
【讨论】:
我刚刚编辑了帖子并放入了一个不同的选择器来调用。但是会出现相同的错误消息,但会使用更新的选择器。为什么 NSString 接收消息而不是 UIButton 对我来说也是一个谜 当一个对象突然“改变类型”时,通常表明你已经过度释放了那个对象并且内存正在被其他东西重用。在代码中设置断点并检查saveButton
的内存地址之前将其添加到[self view]
。然后,检查是否至少与引发异常的内存地址相同。如果是这样,那么您就有了要跟踪的内存错误!【参考方案3】:
刚刚测试了您的代码,它可以工作。也许框架没有正确设置
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *saveButton = [[UIButton alloc] init];
saveButton=[UIButton buttonWithType:UIButtonTypeCustom];
[saveButton setBackgroundImage:[UIImage imageNamed:@"intervalbutton"] forState:UIControlStateNormal];
[saveButton setBackgroundImage:[UIImage imageNamed:@"intervalbuttonpressed"] forState:UIControlStateHighlighted];
saveButton.alpha=.8;
saveButton.frame= CGRectMake(5, 5, 200, 40);
UILabel* label=[[UILabel alloc]initWithFrame:CGRectMake(0, 2, saveButton.frame.size.width, 21)];
label.text = @"Hello";
[saveButton addSubview:label];
[saveButton addTarget:self action:@selector(handleActionSheet:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:saveButton];
-(void)handleActionSheet:(id)sender
NSLog(@"working");
【讨论】:
感谢您的测试。问题是我将应用程序移植到 iPad 上,并简单地复制了实际在 iPhone 上运行的代码。但突然它停止工作了。 设置框架失败不会导致对象被提前释放。以上是关于UIButton 调用选择器使应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
DismissViewController UIButton 导致应用程序在 iPod touch 上崩溃
在使用分配的 IBAction (UIButton) 点击 IBOutlet 后,iOS 应用程序崩溃,没有任何异常