ошибка «нераспознанный селектор отправлен в экземпляр» в Objective-C - PullRequest
146 голосов
/ 16 марта 2010

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

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

Ответы [ 36 ]

176 голосов
/ 16 марта 2010

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

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

124 голосов
/ 31 января 2012

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

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

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

* +1007 *

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

68 голосов
/ 08 июля 2012

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

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

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

24 голосов
/ 20 мая 2013

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

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

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

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

22 голосов
/ 06 марта 2013

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

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

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

14 голосов
/ 18 сентября 2012

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

12 голосов
/ 15 сентября 2012

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

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

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

11 голосов
/ 25 июля 2014

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

5 голосов
/ 14 марта 2013

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

NSArray* array = [[NSArray alloc] init];
[(NSDictionary*)array objectForKey: key]; // array is not a dictionary, hence exception
3 голосов
/ 25 января 2014

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

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

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

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

* +1007 *

Но на самом деле он ищет селектор:

- (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, и это решило проблему для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...