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

StackOverflow https://stackoverflow.com/questions/2455161

Вопрос

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

-[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(@"---");
}
Это было полезно?

Решение

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

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

Другие советы

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

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

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

- (IBAction)buttonPressed {

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

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

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

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

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

Когда используешь:

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

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

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

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

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, который вам также следует прочитать.

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

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

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

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

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

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

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

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

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

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

[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];

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

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

Я удалил свою кнопку ui из раскадровки и воссоздал ее..теперь все работает нормально.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Я использую Xamarin и MvvmCross и пытаюсь привязать UIButton к ViewModel.Я подключил UIButton к Outlet и TouchUpInside.

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

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

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

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

Ваше здоровье.

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

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

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

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

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

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

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

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

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

«Закрытие приложения из-за неперехваченного исключения «NSInvalidArgumentException», причина:»

Проблема заключалась в том, что у меня дважды была подключена кнопка «Ввод» на калькуляторе, и друг отметил, что проверка кнопки в раскадровке показала, что 2 записи были в атрибутах «Редактировать внутри», когда я щелкнул правой кнопкой мыши по ней. кнопку «Ввести».Удаление одного из двух «Отправленных событий» «Редактировать внутри» решило проблему.

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

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

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

Еще одна действительно глупая причина — селектор определен в интерфейсе (.h), но не в реализации (.m) (т.е.опечатка)

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top