ошибка "нераспознанный селектор отправлен в экземпляр" в Objective-C

Я создал кнопку и добавил действие для нее, но как только она была вызвана, я получил эту ошибку:

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

Ответ 1

Похоже, что вы не правильно управляете контроллером представления, и он освобождается в какой-то момент, что приводит к тому, что метод numberButtonClicked: отправляется другому объекту, который теперь занимает память, которую ранее наблюдал контроллер просмотра занимающие...

Убедитесь, что вы правильно удерживаете/отпускаете свой контроллер.

Ответ 2

Для тех, кто попадает сюда через Google, как я, который, вероятно, больше относится к Xcode 4.2 +/iOS 5+, что с ARC. У меня была такая же ошибка " нераспознанный селектор, отправленный экземпляру". В моем случае у меня было целевое действие UIButton, настроенное для передачи себя в качестве параметра отправителя, но позже понял, что мне это не нужно, и удалил его в коде. Итак, что-то вроде:

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

Был изменен на:

- (IBAction)buttonPressed {

Щелчок правой кнопкой мыши по рассматриваемой UIButton показал, что событие Touch Up Inside было связано с элементом управления viewPonted: method. Удаление этого и переназначение его на модифицированный метод обработали удовольствие.

Ответ 3

Это был главный ответ Google для этой проблемы, но у меня была другая причина/результат. Я думал, что добавлю свои два цента, если другие спотыкаются по этой проблеме.

У меня была аналогичная проблема только сегодня утром. Я обнаружил, что если вы щелкните правой кнопкой мыши элемент пользовательского интерфейса, задавая вам проблему, вы увидите, какие соединения были созданы. В моем случае у меня была кнопка, связанная с двумя действиями. Я удалил действия из контекстного меню и переработал их, и моя проблема была исправлена.

Поэтому убедитесь, что вы правильно подключены.

Ответ 4

Хорошо, я должен здесь чип. OP динамически создавал кнопку. У меня была подобная проблема, и ответ (после часов охоты) настолько прост, что мне стало больно.

При использовании:

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

Как обычно, всегда очевидный ответ пропущен.

Ответ 5

В моем случае функция не ожидала аргумента, но кнопка была настроена для отправки одной из них, вызвавшей ошибку. Чтобы исправить это, мне пришлось переделать обработчик событий.

Вот моя функция:

enter image description here

Обратите внимание, что он не содержит аргументов.

Вот изображение конфигурации моей кнопки (щелкните правой кнопкой мыши по кнопке, чтобы просмотреть ее):

enter image description here

Обратите внимание, что есть 3 обработчика событий.

Чтобы исправить это, мне пришлось удалить каждый из элементов события, так как один из них отправил ссылку на себя в функцию enterPressed. Чтобы удалить эти элементы, я нажал на маленькую иконку x рядом с названием каждого элемента, пока не было отображено никаких элементов.

enter image description here

Затем мне пришлось снова подключить кнопку к событию. Для этого нажмите и удерживайте клавишу Control, а затем перетащите строку с кнопки на действие. Он должен сказать "Подключить действие". Примечание. Мне пришлось перезапустить XCode для этого, чтобы работать по какой-то причине; в противном случае он позволяет мне вставлять действия (ака создать новое действие) выше или ниже функции.

enter image description here

Теперь у вас должен быть один обработчик событий, связанный с событием кнопки, который не передает никаких аргументов:

enter image description here

Этот ответ дополняет ответ @Leonard Challis, который вы также должны прочитать.

Ответ 6

Это также может произойти, если вы не устанавливаете "класс" представления в конструкторе интерфейса.

Ответ 7

В моем случае я использовал NSNotificationCenter и пытался использовать селектор, который не принимал аргументов, но добавлял двоеточие. Удаление двоеточия решило проблему.

При использовании имени селектора не используйте завершающий двоеточие, если нет аргументов. Если есть один аргумент, используйте один конечный двоеточие. Если существует более одного аргумента, вы должны назвать их вместе с завершающим двоеточием для каждого аргумента.

Смотрите ответ Адама Розенфилда здесь: Селекторы в Objective-C?

Ответ 8

У меня была эта проблема с проектом 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

Ответ 9

Наиболее очевидной причиной этого (включенной для полноты) является неправильное наведение указателя и вызов метода неправильного класса.

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

Ответ 10

У меня была аналогичная проблема, но для меня решение было несколько иным. В моем случае я использовал Категория для расширения существующего класса (UIImage для некоторых возможностей изменения размера), см. Этот howto в случае вам интересно) и забыл добавить файл *.m в цель сборки. Глупая ошибка, но не всегда очевидна, когда бывает, где искать. Я думал, что стоит поделиться...

Ответ 11

У меня была такая же ошибка, и я обнаружил следующее:

Когда вы используете код

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

Вы можете подумать, что он ищет селектор:

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

Но он действительно ищет селектор:

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

Этот селектор не существует, поэтому вы получаете сообщение об ошибке.

Вы можете изменить селектор для приема (id) отправителя, чтобы решить эту ошибку.

Но что, если у вас есть другие функции, вызывающие функцию обновления без предоставления отправителя? Вам нужна одна функция, которая работает для обоих. Простое решение - добавить еще одну функцию:

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

И затем измените код обновления, чтобы вызвать этот селектор:

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

Я также делаю курс Stanford iOS на более старом Mac, который нельзя обновить до самой новой версии Mac OSX. Поэтому я все еще строю для iOS 6.1, и это решило проблему для меня.

Ответ 12

У меня также была такая же проблема.

Я удалил свой uibutton в своем раскадровке и воссоздал его. Теперь все работает нормально.

Ответ 13

Я думаю, вы должны использовать void вместо IBAction в обратном типе. потому что вы определили кнопку программно.

Ответ 14

Это случилось с моим, потому что случайно стирает "@IBAction func..." внутри моего кода класса UIViewcontroller, поэтому в Storyboard был создан Reference Outlet, но во время выполнения была любая функция для его обработки.

Решение заключалось в том, чтобы удалить ссылку Outlet внутри инспектора свойств, а затем воссоздать ее перетаскивание с помощью командной строки в код класса.

Надеюсь, что это поможет!

Ответ 15

В настоящее время я изучаю разработку iOS и просматриваю книгу "Начало разработки iOS6" от aPress. Я получал ту же ошибку в главе 10: Раскадровки.

Мне потребовалось два дня, чтобы понять это, но выяснил, что я случайно установил тег ячейки TableView равным 1, когда мне этого не было. Для тех, кто еще делает эту книгу и получает подобную ошибку, я надеюсь, что это поможет.

Я действительно надеюсь, что будущие ошибки в моем коде легче найти! хахаха. Ошибка отладки не сделала ничего, чтобы подтолкнуть меня в правильном направлении, чтобы понять это (или, по крайней мере, я слишком новичок, чтобы понять отладчик, lol).

Ответ 16

В моем случае я использовал UIWebView, и я передал NSString во втором параметре вместо NSURL. Поэтому я подозреваю, что неправильные типы классов, переданные функциям, могут вызвать эту ошибку.

Ответ 17

.. А теперь мой

У меня была кнопка, связанная с методом, который обращался к другому параметру кнопки, и это отлично работало, но как только я попытался что-то сделать с самой кнопкой, я получил сбой. При компиляции ошибка не отображается. Решение?

Мне не удалось связать кнопку с владельцем файла. Итак, если кто-то здесь такой же глупый, как и я, попробуйте это:)

Ответ 18

Еще одно немного другое решение/случай.

Я использую Xamarin и MvvmCross, и я пытался привязать UIButton к ViewModel. У меня был UIButton, подключенный к Outlet и TouchUpInside.

При привязке я использую только выход:

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

Все, что мне нужно было сделать, это удалить соединение (TouchUpInside) в XCode и решить его.

P.S. Я думаю, что это в его основе все связано с предыдущими ответами и с @Chris Kaminski в частности, но я надеюсь, что это поможет кому-то...

Приветствия.

Ответ 19

У меня была такая же проблема. Проблема для меня заключалась в том, что одна кнопка имела два метода Action. То, что я сделал, это создать первый метод действий для моей кнопки, а затем удалить его в контроллере представления, но забыл отключить соединение в основной раскадровке в инспекторе соединений. Поэтому, когда я добавил второй метод действия, для одной кнопки было два метода действий, которые вызвали ошибку.

Ответ 20

Для меня это было остаточное соединение, созданное в интерфейсе bij ctrl-dragging. Имя сломанного соединения было в журнале ошибок

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

У меня было действие, связанное с кнопкой. Нажатие кнопки разбило приложение, потому что Outlet больше не существовал в моем коде. Поиск имени в журнале привел меня к нему в раскадровке. Удалил его, и авария исчезла!

Ответ 21

В моем случае я решил проблему через 2 часа:

У отправителя (элемента tabBar) не было ни одного источника ссылок. Так что это никуда не указывало.

Juste создайте ссылочный выход, соответствующий вашей функции.

Надеюсь, это поможет вам, ребята.

Ответ 22

Я отвечаю на Леонарда Чаллиса, так как я также принимал Стэнфордский iOS класс C193P, как и пользователь "oli206"

"Завершение приложения из-за неперехваченного исключения" NSInvalidArgumentException ", причина:"

Проблема заключалась в том, что у меня была кнопка "Enter" на калькуляторе, подключенной дважды, и друг указал, что проверка проверки кнопки в раскадровке показала, что 2 записи были в атрибутах "Touch Up Inside", когда я щелкните правой кнопкой мыши по кнопке "Enter". Стирание одного из двух "Touch Up Inside" "Отправленные события" решило проблему.

Это показало, что проблема запускается (для класса видео C193P в прохождении калькулятора по назначению 1) в виде 2 отправленных событий, одна из которых вызывала исключение.

Ответ 23

Это может произойти, если вы не назначили ViewController ViewControllerScene в InterfaceBuilder. Поэтому ViewController.m не подключен к какой-либо сцене.

Ответ 24

Включая мою долю. Я застрял на этом некоторое время, пока не понял, что создал проект с ARC (Автоматическая ссылка). Быстрый набор YES для этой опции решил мою проблему.

Ответ 25

Другая действительно глупая причина этого заключается в том, что селектор определен в интерфейсе (.h), но не в реализации (.m) (p.e. typo)

Ответ 26

Еще одна причина/решение для добавления в список. Это вызвано 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, даже на том же самом устройстве, развернутом на разных устройствах.

Я не понимаю, почему компилятор не сказал мне об этом, так или иначе, - проблема была решена.

Ответ 27

Это также может произойти, если вы хотите установить свойство из ControllerA в общедоступное свойство внутри пользовательского класса ControllerB, и вы еще не установили "Пользовательский класс" внутри инспектора идентификации в раскадках.

Ответ 28

Другое возможное решение: добавьте '-ObjC' к вашим аргументам компоновщика.

Полное объяснение здесь: Objective-C категории в статической библиотеке

Я думаю, что суть: если категория определена в библиотеке, с которой вы статически связываетесь, компоновщик недостаточно умен, чтобы ссылаться на методы категории. Флаг выше делает ссылку ссылки во всех объективных классах C и категориях, а не только на тех, которые, по его мнению, должны основываться на анализе вашего источника. (Пожалуйста, не стесняйтесь настраивать или исправлять этот ответ. Я знаю, что связан с языками, поэтому я просто разбираюсь здесь).

Ответ 29

Моя проблема и решение были разными, и я подумал, что должен опубликовать его здесь, чтобы будущие читатели могли спасти голову от удара по стене.

Я распределял разные xib на тот же UIVIewController, и даже после поиска везде я не мог найти, как его исправить. Затем я проверил свой AppDelegate, где я звонил initWithNibName, и вижу, что при копировании кода я изменил имя xib, но забыл изменить класс UIViewController. Поэтому, если ни одно из решений не работает для вас, проверьте свой метод initWithNibName.

Ответ 30

Случилось мне из-за противоречивых аргументов ограничения.