169

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

-[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'

这是我的代码:

- (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(@"---");
}
4

39 回答 39

193

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

确保您正确保留/释放您的视图控制器。

于 2010-03-16T14:40:08.313 回答
133

对于那些像我一样通过谷歌到达这里的人,这可能更多地与 Xcode 4.2+/iOS 5+ 有关,ARC 是什么。我有同样的错误“无法识别的选择器发送到实例”。在我的情况下,我设置了一个 UIButton 的目标操作以将其自身作为 sender 参数传递,但后来意识到我不需要它并在代码中将其删除。所以,像:

- (IBAction)buttonPressed:(UIButton *)sender {

改为:

- (IBAction)buttonPressed {

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

于 2012-01-31T18:09:26.497 回答
79

这是这个问题的最佳谷歌答案,但我有不同的原因/结果——我想我会加两分钱,以防其他人偶然发现这个问题。

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

因此,请确保您的操作正确。

于 2012-07-08T15:19:24.467 回答
25

好的,我必须在这里筹码。OP动态创建了 button。我有一个类似的问题,答案(经过几个小时的狩猎)非常简单,让我感到恶心。

使用时:

action:@selector(xxxButtonClick:)

or (as in my case)

action:NSSelectorFromString([[NSString alloc] initWithFormat:@"%@BtnTui:", name.lowercaseString])

如果您在字符串的末尾放置一个冒号 - 它将通过发件人。如果你不把冒号放在字符串的末尾,它就不会,如果接收器需要一个,它将得到一个错误。如果您是动态创建事件名称,很容易漏掉冒号。

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

- (void)doneBtnTui:(id)sender {
  NSLog(@"Done Button - with sender");
}
 or
- (void)doneBtnTui {
  NSLog(@"Done Button - no sender");
}

像往常一样,总是错过明显的答案。

于 2013-05-20T16:33:42.733 回答
24

In my case the function was not expecting an argument but the button was configured to send one causing the error. To fix this I had to rewire the event handler.

Here is my function:

enter image description here

Notice it contains no arguments.

Here is an image of my button configuration (right click on the button to view it):

enter image description here

Notice there are 3 event handlers.

To fix this I had to remove each of the event items since one of them was sending a reference to itself to the enterPressed function. To remove these items I clicked on the little x icon next to the name of each item until there were no items shown.

enter image description here

Next I had to reconnect the button to the event. To do this hold down the Control key and then drag a line from the button to the action. It should say "Connect Action". Note: I had to restart XCode for this to work for some reason; otherwise it only let me insert actions (aka create a new action) above or below the function.

enter image description here

You should now have a single event handler wired to the button event that passes no arguments:

enter image description here

This answer compliments the answer by @Leonard Challis which you should read as well.

于 2013-03-05T21:31:55.227 回答
14

如果您没有在界面生成器中设置视图的“类”,也会发生这种情况。

于 2012-09-18T17:51:43.867 回答
13

就我而言,我正在使用 NSNotificationCenter 并尝试使用不带参数但添加冒号的选择器。删除冒号解决了这个问题。

使用选择器名称时,如果没有参数,请勿使用尾随冒号。如果有一个参数,请使用一个尾随冒号。如果有多个参数,则必须为它们命名,并为每个参数加上一个尾随冒号。

在此处查看 Adam Rosenfield 的回答:Objective-C 中的选择器?

于 2012-09-15T03:40:57.500 回答
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).")
}

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

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).")
    }

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

于 2014-07-25T16:18:14.273 回答
8

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

NSArray* array = [[NSArray alloc] init];
[(NSDictionary*)array objectForKey: key]; // array is not a dictionary, hence exception
于 2013-03-13T20:39:21.930 回答
4

我也有同样的问题。

我在情节提要中删除了我的 uibutton 并重新创建了它..现在一切正常。

于 2017-01-11T15:10:01.677 回答
3

我有一个类似的问题,但对我来说解决方案略有不同。就我而言,我使用 Category 来扩展现有类(UIImage 用于一些调整大小的功能 - 如果您感兴趣,请参阅此操作指南)并且忘记将 *.m 文件添加到构建目标。愚蠢的错误,但当它发生在哪里看时并不总是很明显。我觉得值得分享...

于 2012-11-07T10:23:22.377 回答
3

另一种可能的解决方案:将“-ObjC”添加到链接器参数中。

完整的解释在这里:Objective-C categories in static library

我认为要点是:如果类别是在您静态链接的库中定义的,则链接器不够聪明,无法链接类别方法。上面的标志使链接器链接到所有目标 C 类和类别中,而不仅仅是它认为基于分析您的源代码需要的链接器链接。(请随时调整或更正该答案。我知道链接语言,所以我只是在这里鹦鹉学舌)。

于 2013-02-18T16:56:36.443 回答
3

这发生在我身上,因为不小心删除了 UIViewcontroller 类代码中的“@IBAction func...”,所以在 Storyboard 中创建了 Reference Outlet,但在运行时有任何函数可以处理它。

解决方案是删除属性检查器内的 Outlet 引用,然后使用命令键将其拖动到类代码中重新创建它。

希望能帮助到你!

于 2017-01-14T15:03:41.363 回答
2

我有同样的错误,我发现了以下内容:

当您使用代码时

[self.refreshControl addTarget:self action:@selector(yourRefreshMethod:) forControlEvents:UIControlEventValueChanged];

您可能认为它正在寻找选择器:

- (void)yourRefreshMethod{
    (your code here)
}

但它实际上是在寻找选择器:

- (void)yourRefreshMethod:(id)sender{
    (your code here)
}

该选择器不存在,因此您会崩溃。

您可以将选择器更改为接收 (id)sender 以解决错误。

但是,如果您有其他函数调用刷新函数而不提供发送者怎么办?您需要一种对两者都适用的功能。简单的解决方案是添加另一个功能:

- (void)yourRefreshMethodWithSender:(id)sender{
    [self yourRefreshMethod];
}

然后修改刷新下拉代码以调用该选择器:

[self.refreshControl addTarget:self action:@selector(yourRefreshMethodWithSender:) forControlEvents:UIControlEventValueChanged];

我还在无法升级到最新版本的 Mac OSX 的旧 Mac 上学习斯坦福 iOS 课程。所以我仍在为 iOS 6.1 构建,这解决了我的问题。

于 2014-01-25T17:37:20.210 回答
2

我认为您应该在返回类型中使用 void,而不是 IBAction。因为您以编程方式定义了一个按钮。

于 2012-09-11T15:28:47.287 回答
2

就我而言,我在 2 小时后解决了问题:

发件人(一个 tabBar 项目)没有任何引用 Outlet。所以它没有指向任何地方。

Juste创建一个与您的功能相对应的引用出口。

希望这可以帮助你们。

于 2018-08-24T13:30:54.153 回答
1

我目前正在学习 iOS 开发,并正在阅读 aPress 的“Beginning iOS6 Development”一书。我在第 10 章:故事板中遇到了同样的错误。

我花了两天时间才弄明白,但发现我不应该将 TableView 单元格的标签设置为 1。对于其他读这本书并收到类似错误的人,我希望这会有所帮助。

我真的希望我的代码中的未来错误更容易找到!哈哈哈。调试错误并没有将我推向正确的方向来解决它(或者至少我太新了,无法理解调试器,哈哈)。

于 2013-03-28T11:31:44.687 回答
1

就我而言,我使用的是 UIWebView,并且在第二个参数中传递了 NSString 而不是 NSURL。所以我怀疑传递给函数的错误类类型会导致这个错误。

于 2013-04-02T21:20:40.540 回答
1

..现在我的

我将按钮链接到一个访问另一个按钮参数的方法,并且效果很好,但是当我尝试对按钮本身做一些事情时,我就崩溃了。编译时,没有显示错误。。解决办法?

我未能将按钮链接到文件的所有者。所以如果这里有人像我一样愚蠢,试试这个:)

于 2014-03-24T17:16:07.747 回答
1

另一个略有不同的解决方案/案例。

我正在使用 Xamarin 和 MvvmCross,并且试图将 UIButton 绑定到 ViewModel。我将 UIButton 连接到 Outlet 和 TouchUpInside。

装订时我只使用插座:

set.Bind (somethingOutlet).For ("TouchUpInside").To(vm => vm.Something);

我所要做的就是删除 XCode 中的操作 (TouchUpInside) 连接并解决了它。

PS我想这在其基础上都与先前的答案有关,尤其是与@Chris Kaminski有关,但我希望这对某人有所帮助...

干杯。

于 2015-03-20T00:35:48.117 回答
1

我遇到过同样的问题。对我来说,问题是一个按钮有两个 Action 方法。我所做的是为我的按钮创建第一个操作方法,然后在视图控制器中将其删除,但忘记在连接检查器的主情节提要中断开连接。所以当我添加第二个动作方法时,现在一个按钮有两个动作方法,这导致了错误。

于 2016-03-01T22:22:33.683 回答
1

对我来说,这是在 interfacebuilder bij ctrl-dragging 中创建的剩余连接。断开连接的名称在错误日志中

*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[NameOfYourApp.NameOfYourClass nameOfCorruptConnection:]:
unrecognized selector sent to instance 0x7f97a48bb000'

我有一个链接到按钮的操作。按下按钮会使应用程序崩溃,因为 Outlet 不再存在于我的代码中。在日志中搜索名称导致我在情节提要中找到它。删除它,崩溃消失了!

于 2016-09-12T09:32:29.560 回答
1
于 2021-02-01T17:14:09.390 回答
0

我正在回复 Leonard Challis,因为我也参加了斯坦福 iOS 课程 C193P,用户“oli206”也是如此

“由于未捕获的异常‘NSInvalidArgumentException’而终止应用程序,原因:”

问题是我将计算器上的“Enter”按钮连接了两次,一位朋友指出,在 Storyboard 中检查按钮显示当我右键单击时,“Touch Up Inside”属性上有 2 个条目“输入”按钮。删除两个“Touch Up Inside”“发送事件”之一解决了这个问题。

这表明问题被触发(对于作业 1 的计算器演练中的 C193P 视频类)作为 2 个发送事件,其中一个导致异常。

于 2012-10-12T14:41:16.893 回答
0

当您没有将 ViewController 分配给 InterfaceBuilder 中的 ViewControllerScene 时,可能会发生这种情况。所以 ViewController.m 没有连接到任何场景。

于 2012-11-15T12:13:19.600 回答
0

添加到列表中的另一个原因/解决方案。这是由 iOS6.0(和/或糟糕的编程)引起的。在旧版本中,如果参数类型匹配,则选择器将匹配,但在 iOS 6.0 中,我在之前工作的代码中遇到了参数名称不正确的崩溃。

我正在做类似的事情

[objectName methodName:@"somestring" lat:latValue lng:lngValue];

但在定义中(.h 和 .m)我有

(viod) methodName:(NSString *) latitude:(double)latitude longitude:(double)longitude;

这在 iOS5 上运行良好,但在 6 上运行良好,即使是完全相同的构建部署到不同的设备。

无论如何,我不明白为什么编译器不能告诉我这个 - 问题已解决。

于 2013-01-10T04:23:53.207 回答
0

当您想将 ControllerA 中的属性设置为自定义 ControllerB 类中的公共属性并且您尚未在情节提要中的身份检查器中设置“自定义类”时,也可能会发生这种情况。

于 2013-02-05T02:47:27.850 回答
0

另一个非常愚蠢的原因是在接口(.h)中定义了选择器,但在实现(.m)中没有定义(pe错字)

于 2012-12-13T10:54:40.063 回答
0

我的问题和解决方案不同,我想我应该把它贴在这里,这样未来的读者就可以免于撞墙了。

我将不同的 xib 分配给同一个 UIVIewController ,即使在到处搜索之后我也找不到如何纠正它。然后我检查了我正在调用的 AppDelegate,initWithNibName可以看到在复制代码时,我更改了 xib 名称,但忘记更改UIViewController类。因此,如果没有一个解决方案适合您,请检查您的initWithNibName方法。

于 2013-08-10T22:13:00.460 回答
0

基础:动态调用

目标 C 是一种动态语言,它通过查看类中方法的运行时来调用方法。例如,如果A 类包含方法DoSomething(arg1, arg2)如果您尝试在A 类对象上使用正确的参数调用该方法,一切都会正常工作。但是,如果参数未正确传递,例如,您仅使用一个参数调用该方法,则运行时会将其视为对不同方法的方法调用。最终,运行时将无法找到方法(DoSomething 有一个参数),并会通过这个异常"unrecognized selector sent to instance"

解决方案

请检查@selector的预期签名。通常是,正如您在代码中描述的那样

-(IBAction)numberButtonClick:(id)sender{
于 2014-05-14T11:13:40.093 回答
0

包括我的份额。我被困了一段时间,直到我意识到我已经创建了一个禁用ARC(自动计数引用)的项目。在该选项上快速设置为 YES 解决了我的问题。

于 2012-12-03T21:24:32.253 回答
0

由于冲突的约束参数而发生在我身上。

于 2013-11-07T23:36:12.303 回答
0

在我的例子中,在 iOS 13 中,我只需要实现整个函数和选择器调用部分放入主线程。

于 2020-08-21T05:10:55.213 回答
0

我在Swift3中尝试一些旧格式代码时遇到了这个问题,

let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respond))

改变action:"respond:"行动:#selector(self.respond)为我解决了这个问题。

于 2016-11-04T08:44:29.690 回答
0

我也遇到了这个问题,最后我找到了我的问题的解决方案。我controller's UI在 storyboard 中构建了,但是controller's UI没有将它的控制与代码联系起来,我使用这个代码来初始化vc

    UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Me" bundle:nil];
    [sb instantiateViewControllerWithIdentifier:@"HeaderViewController"];

上面的代码会导致问题,在我将init代码更改为下面的代码后,我解决了问题:

HeaderViewController *head_vc = [[HeaderViewController alloc] init];
于 2016-07-21T05:41:29.240 回答
0

OK LISTED UP! I'm VERY new to XCODE, had this problem, and figured it out! So if that sounds like you, here's the answer:

When you control + click and drag the button to your ViewController file (so you can code it), you will be asked to fill out the properties of the button in a popup.

The bottom of the popup (under Type) will say "SENDER".

YOU NEED TO CHANGE IT TO "NONE"

于 2020-08-16T22:00:44.617 回答
0

我的情况是:view 中的 collectionView

我试图在config()我自己编写的方法中添加gestureRecognizer。经过一些解决方法后,我发现我只需将代码移动到awakeFromNib().

override func awakeFromNib() {

   //other code

   let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongGesture(gesture:)))
   self.collectionView.addGestureRecognizer(longPressGesture)
}

而且效果很好。

我希望这可以帮助某人。

于 2018-06-06T12:08:20.600 回答
0

就我而言:

我的协议定义

 @protocol MyProtocol

- (void)Method;

@end

我忘了实现委托方法。

希望它可以帮助某人。

于 2018-08-23T03:48:56.423 回答
0

我从 Swift 2 切换到 Swift 3 后遇到了这个问题。下面的描述是具体的,但你可以看到它的一般情况涵盖了很多可能的错误。

delete我在我的子类中调用了一个方法SKNode

func delete(thing: SomeType) 

delete上已经有一个方法UIResponder,但是我的方法(无意中)重载了它,所以它工作正常。升级到 Swift 3 将其更改为:

func delete(_ thing: SomeType) 

还在工作。但后来我决定对它进行 Swift3ify 并强制参数:

func delete(thing: SomeType)

如果我记得更新调用者,这会很好,但我现在没有这样做,调用者使用错误类型的参数调用 no-parameter-namedelete方法。UIResponder

SKNode这显然可能发生在(并且可能UIView)上Any作为参数的一长串标准方法中的任何一个,因此将通过编译阶段,但在调用时会失败。

于 2017-03-10T20:47:21.283 回答