Objective-C中的"无法识别的选择器发送到实例"错误

Hel*_*rld 151 objective-c selector unrecognized-selector

我创建了一个按钮,并为其添加了一个动作,但是一旦调用它,我就收到了这个错误:

-[NSCFDictionary numberButtonClick:]: unrecognized selector sent to instance
 0x3d03ac0 2010-03-16 22:23:58.811
 Money[8056:207] *** Terminating app
 due to uncaught exception
 'NSInvalidArgumentException', reason:'*** -[NSCFDictionary numberButtonClick:]:  unrecognized selector sent to instance 0x3d03ac0'
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        UIButton *numberButton = [UIButton buttonWithType:UIButtonTypeCustom];        
        numberButton.frame = CGRectMake(10, 435, 46, 38);
        [numberButton setImage:[UIImage imageNamed:@"one.png"] forState:UIControlStateNormal];
        [numberButton addTarget:self action:@selector(numberButtonClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview: numberButton]; 
    }
return self;
}

-(IBAction)numberButtonClick:(id)sender{
    NSLog(@"---");
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*ien 181

看起来你没有正确管理视图控制器的内存,并且它在某些时候被释放 - 这导致该numberButtonClicked:方法被发送到另一个对象,该对象现在占用了视图控制器以前占用的内存...

确保正确保留/释放视图控制器.

  • 从很少的代码行开始,这是一个非常精明的诊断. (103认同)
  • 好的,所以问题确定了......但是"确保你正确地保留/释放你的视图控制器." 是一个建议,而不是解决方案. (40认同)
  • 正确.虽然这似乎是"修复"..我可能是少数,(虽然我仍然设法存在),但问题和解决方案之间的联系并不是立即显而易见的.例如,我遇到` - [NSWindow end]:无法识别的选择器发送到实例0x100523e80`虽然我意识到与OP的相似之处,甚至可能是你答案的问题的原因,修复的实现并不是立竿见影的 (27认同)
  • @alex灰色,什么?视图控制器上的正确内存管理解决了这个问题......我不明白这不是一个解决方案? (12认同)
  • 这很明显.您的NSWindow内存管理在某个地方不正确.通过它的生命周期并纠正它. (12认同)

Leo*_*lis 126

对于那些像我一样通过谷歌来到这里的人,可能更多的是Xcode 4.2 +/iOS 5+以及ARC.我有同样的错误" 无法识别的选择器发送到实例 ".在我的情况下,我有一个UIButton的目标动作设置为传递自己作为发送者参数,但后来意识到我不需要它并在代码中删除它.所以,像:

- (IBAction)buttonPressed:(UIButton *)sender {
Run Code Online (Sandbox Code Playgroud)

改为:

- (IBAction)buttonPressed {
Run Code Online (Sandbox Code Playgroud)

右键单击有问题的UIButton显示Touch Up Inside事件与视图控制器buttonPressed:方法相关联.删除它并将其重新分配给修改后的方法是一种享受.

  • 非常有帮助的回应 我刚遇到这个问题,你的解决方案是完全正确的.当发生这种情况时,在iTunesU上关注斯坦福iOS课程.再次感谢您的回答! (8认同)

Chr*_*s K 72

这是谷歌在这个问题上的最佳答案,但我有不同的原因/结果 - 我想我会加上我的两分钱,万一其他人偶然发现了这个问题.

我今天早上有类似的问题.我发现如果您右键单击提示问题的UI项,您可以看到已创建的连接.在我的情况下,我有一个按钮连接到两个动作.我从右键菜单中删除了操作并重新连接它们,我的问题得到了解决.

因此,请确保您的操作正确连接.

  • 谢谢!事实证明我有三个我删除的方法仍然被引用.困扰我一个星期! (2认同)

小智 24

好的,我必须在这里筹码.OP 动态创建了按钮.我有一个类似的问题,答案(经过几个小时的狩猎)是如此简单,它让我生病了.

使用时:

action:@selector(xxxButtonClick:)

or (as in my case)

action:NSSelectorFromString([[NSString alloc] initWithFormat:@"%@BtnTui:", name.lowercaseString])
Run Code Online (Sandbox Code Playgroud)

如果在字符串的末尾放置一个冒号 - 它将通过发送者.如果你没有将冒号放在字符串的末尾,它就不会,并且接收器如果需要的话会收到错误.如果要动态创建事件名称,很容易错过冒号.

接收器代码选项如下所示:

- (void)doneBtnTui:(id)sender {
  NSLog(@"Done Button - with sender");
}
 or
- (void)doneBtnTui {
  NSLog(@"Done Button - no sender");
}
Run Code Online (Sandbox Code Playgroud)

像往常一样,它总是明显的答案被错过.


1.2*_*tts 23

在我的情况下,该函数不期望参数,但按钮被配置为发送导致错误的按钮.为了解决这个问题,我必须重新连接事件处理程序.

这是我的功能:

在此输入图像描述

注意它不包含任何参数.

这是我的按钮配置的图像(右键单击按钮查看它):

在此输入图像描述

请注意,有3个事件处理程序.

为了解决这个问题,我不得不删除每个事件项,因为其中一个事件项是向enterPressed函数发送自身引用.要删除这些项目,我会点击每个项目名称旁边的小x图标,直到没有显示任何项目.

在此输入图像描述

接下来我不得不重新连接事件的按钮.要执行此操作,请按住Control键,然后从按钮拖动一条线到操作.应该说"连接动作".注意:出于某种原因,我必须重新启动XCode才能正常工作; 否则它只允许我在函数的上方或下方插入动作(也就是创建一个新动作).

在此输入图像描述

您现在应该有一个事件处理程序连接到不传递任何参数的按钮事件:

在此输入图像描述

这个答案与@Leonard Challis的答案相辅相成,您也应该阅读.


小智 14

如果未在界面生成器中设置视图的"类",也会发生这种情况.


Nat*_*ian 12

在我的情况下,我正在使用NSNotificationCenter并尝试使用不带参数的选择器,但是添加了一个冒号.删除冒号修复了问题.

使用选择器名称时,如果没有参数,请不要使用尾随冒号.如果有一个参数,请使用一个尾随冒号.如果有多个参数,则必须为每个参数命名它们以及尾部冒号.

请参阅Adam Rosenfield的答案:Objective C中的选择器


Fre*_*edL 11

我在Swift项目中遇到了这个问题,我正在动态创建按钮.问题代码:

var trashBarButtonItem: UIBarButtonItem {
    return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked")
}

func newButtonClicked(barButtonItem: UIBarButtonItem) {
    NSLog("A bar button item on the default toolbar was clicked: \(barButtonItem).")
}
Run Code Online (Sandbox Code Playgroud)

解决方案是在动作后添加一个完整的冒号':':例如

var trashBarButtonItem: UIBarButtonItem {
        return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked:")
    }

    func newButtonClicked(barButtonItem: UIBarButtonItem) {
        NSLog("A bar button item on the default toolbar was clicked: \(barButtonItem).")
    }
Run Code Online (Sandbox Code Playgroud)

完整示例:https://developer.apple.com/library/content/samplecode/UICatalog/Listings/Swift_UIKitCatalog_DefaultToolbarViewController_swift.html


dev*_*os1 6

最明显的原因(包括完整性)是不正确地转换指针并调用错误类的方法.

NSArray* array = [[NSArray alloc] init];
[(NSDictionary*)array objectForKey: key]; // array is not a dictionary, hence exception
Run Code Online (Sandbox Code Playgroud)


Ike*_*bal 5

如何调试\xe2\x80\x98无法识别的选择器发送到实例\xe2\x80\x99

\n

在大多数情况下,Xcode 不会将我们带到发生此问题的确切行。当应用程序崩溃时,您不会\xe2\x80\x99看到导致此问题的代码行,而是会被带到应用程序委托类,其中错误输出可能如下所示:

\n
[UITableViewCellContentView image]: unrecognized selector sent to instance\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
*** Terminating app due to uncaught exception \'NSInvalidArgumentException\', reason: \'-[TestApp.MyViewController viewDidLoad:]: unrecognized selector sent to instance 0xDABCDD\'\n
Run Code Online (Sandbox Code Playgroud)\n

如何找到导致此问题的代码行:

\n

转到断点导航器。单击\xe2\x80\x98+\xe2\x80\x99 选项。单击 \xe2\x80\x98Exception 断点\xe2\x80\x99。将出现如下所示的新小部件。

\n

在此输入图像描述

\n

添加以下条件块:

\n
-[NSObject(NSObject) doesNotRecognizeSelector:]\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

您还可以为所有异常设置断点。\n现在再次运行您的代码。这次,当这个异常发生时,就会触发断点。

\n

编剧:普拉富拉·辛格

\n

完整说明:https://prafullkumar77.medium.com/how-to-debug-unrecognized-selector-send-to-instance-402473bc23d

\n