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 上崩溃

UIButton点击崩溃应用

在使用分配的 IBAction (UIButton) 点击 IBOutlet 后,iOS 应用程序崩溃,没有任何异常

UIButton Clicked for Webview 加载到 ipad 后应用程序崩溃

Swift - 可达性崩溃

uipageviewcontroller内的UIbutton点击崩溃