Objective-C에서 "인식 할 수없는 선택기가 인스턴스로 전송되었습니다"오류


155

버튼을 만들고 해당 작업을 추가했지만 호출하자마자이 오류가 발생했습니다.

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

답변:


187

뷰 컨트롤러를 올바르게 관리하는 메모리가 아니며 어느 시점에서 할당이 해제되는 것처럼 보입니다. 이는 numberButtonClicked:뷰 컨트롤러가 이전에 차지했던 메모리를 차지하는 다른 객체로 메소드가 전송되도록합니다 ...

뷰 컨트롤러를 올바르게 유지 / 해제해야합니다.


105
그것은 몇 줄의 코드에서 매우 현명한 진단입니다.
— 마이클 모리슨

41
문제가 확인 되었으나 "뷰 컨트롤러를 올바르게 유지 / 해제해야합니다." 해결책이 아니라 제안입니다.
— Alex Gray

12
@alex grey, 뭐? 뷰 컨트롤러의 적절한 메모리 관리로 문제가 해결되었습니다 ... 솔루션이 아닌 방법을 이해하지 못합니까?
— Jasarien

28
옳은. 비록 이것이 "수정"인 것처럼 보이지만 (나는 여전히 존재하지만) 소수에있을 수 있지만 문제와 솔루션 사이의 연결은 즉시 명백하지 않습니다. 예를 들어, 나는 직면 -[NSWindow end]: unrecognized selector sent to instance 0x100523e80 하고 있으며 OP와의 유사점, 심지어 귀하의 답변으로 인한 문제의 원인을 알고 있지만 수정의 구현은 즉시 명백하지 않습니다
— Alex Gray

12
그것은 즉시 명백하다. NSWindow 메모리 관리가 라인 어딘가에 올바르지 않습니다. 수명주기를 거쳐 수정하십시오.
— Jasarien

127

내가했던 것처럼 Google을 통해 여기에 오는 사람들에게는 아마도 ARC의 Xcode 4.2 + / iOS 5 이상에 더 관련이 있습니다. " 인식 할 수없는 선택기가 인스턴스로 전송되었습니다 "와 동일한 오류가 발생했습니다 . 필자의 경우 UIButton의 대상 작업을 발신자 매개 변수로 전달하도록 설정했지만 나중에 필요하지 않고 코드에서 제거했습니다. 따라서 다음과 같은 것이 있습니다.

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

로 변경되었습니다 :

- (IBAction)buttonPressed {

문제의 UIButton을 마우스 오른쪽 버튼으로 클릭하면 Touch Up Inside 이벤트가 뷰 컨트롤러 buttonPressed : 메서드와 관련이 있음을 보여주었습니다. 이것을 제거하고 수정 된 메소드에 다시 할당하면 대우를했습니다.


나는 그 자신의 질문과 대답이 찾기가 더 쉬울 것이라고 생각했지만 매우 도움이되었습니다.
— Curtis Inderwiesche

@LeonardChallis 매개 변수로 전달되지 않은 경우 buttonPressed에서 발신자를 어떻게 참조 할 수 있습니까?
— zakdances

8
매우 유용한 답변입니다. 방금이 정확한 문제에 부딪 쳤고 귀하의 솔루션이 정확히 맞았습니다. 이 일이 발생했을 때 iTunesU에서 Stanford iOS 클래스를 따르고있었습니다. 귀하의 답변에 다시 한번 감사드립니다!
— Marshall Alsup

1
@LeonardChallis 감사합니다. 귀하의 답변에 무료 답변을 추가했습니다.
— 1.21 기가 와트

1
방금 비슷한 문제로 어려움을 겪고 있었고 선택기 기능에서 발신자 매개 변수를 제거한 다음 발신자를 얻는 방법에 대해 궁금했습니다. 필자의 경우 선택기 콜백 뒤에 콜론을 넣지 않아 호출 시퀀스가 ​​일치하지 않아 오류가 발생했습니다. 콜론을 사용하면 발신자 인수를 유지할 수 있습니다.

74

이것은이 문제에 대한 Google의 최고 답변이지만 다른 원인 / 결과가있었습니다. 다른 사람들 이이 문제를 우연히 발견 할 경우 2 센트를 더할 것이라고 생각했습니다.

오늘 아침에 비슷한 문제가 발생했습니다. 문제를 제공하는 UI 항목을 마우스 오른쪽 버튼으로 클릭하면 어떤 연결이 생성되었는지 확인할 수 있습니다. 제 경우에는 두 가지 동작으로 연결된 버튼이 있습니다. 마우스 오른쪽 버튼 클릭 메뉴에서 작업을 삭제하고 다시 연결하여 문제를 해결했습니다.

따라서 작업이 올바르게 연결되어 있는지 확인하십시오.


이것은 내 문제였다. 함수의 이름을 바꾸고 코드를 변경했지만 xib 파일의 연결은 변경하지 않았습니다.
— BFTrick

2
감사합니다! 내가 삭제 한 세 가지 방법이 여전히 참조 된 것으로 나타났습니다. 일주일 동안 귀찮게!
— erdekhayser

25

좋아, 나는 여기에 칩을 넣어야한다. 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");
}

평소와 같이 항상 놓치는 것은 분명한 대답입니다.


1
정말 고마워! 이것은 내 문제였습니다 (선택 자의 이름 끝에 콜론 ':'을 넣지 마십시오). 아침에 새벽 3시에 벽에 머리를 두드리는 괴짜들이 가장 어리석은 간단한 일이 어떻습니까? 정말 고마워!
— TWright

23

필자의 경우 함수는 인수를 기대하지 않았지만 버튼은 오류를 발생시키는 버튼을 보내도록 구성되었습니다. 이 문제를 해결하려면 이벤트 처리기를 다시 연결해야했습니다.

내 기능은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

인수가 포함되어 있지 않습니다.

내 버튼 구성 이미지는 다음과 같습니다 (버튼을 마우스 오른쪽 버튼으로 클릭하면 볼 수 있음).

여기에 이미지 설명을 입력하십시오

3 개의 이벤트 핸들러가 있습니다.

이 문제를 해결하려면 각 이벤트 항목 중 하나가 enterPressed 함수에 대한 참조를 전송했기 때문에 각 이벤트 항목을 제거해야했습니다. 이 항목을 제거하려면 항목이 표시되지 않을 때까지 각 항목 이름 옆에있는 작은 x 아이콘을 클릭했습니다.

여기에 이미지 설명을 입력하십시오

다음으로 버튼을 이벤트에 다시 연결해야했습니다. 이렇게하려면 Control 키를 누른 상태에서 단추에서 동작으로 선을 드래그하십시오. "연결 작업"이라고 표시되어야합니다. 참고 : 어떤 이유로 든 XCode를 다시 시작해야했습니다. 그렇지 않으면 함수 위 또는 아래에 액션 (일명 새 액션 만들기)을 삽입 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

이제 인수가없는 버튼 이벤트에 연결된 단일 이벤트 핸들러가 있어야합니다.

여기에 이미지 설명을 입력하십시오

이 답변은 @Leonard Challis의 답변을 칭찬합니다.


14

인터페이스 빌더에서보기의 "클래스"를 설정하지 않은 경우에도 발생할 수 있습니다.


아 감사합니다! 이것은 내 응용 프로그램이 segue에서 충돌하게하고 컨트롤러의 클래스를 설정하는 것을 잊어 버렸습니다.
— Eichhörnchen 2016 년

왜 수업을 알아야합니까? UITableViewSection을 UIView로 사용하려고 하는데이 오류가 발생합니다. 컴파일러는 UITableViewSection이 존재하지 않으므로 UIKit 내부를 가정합니다.
— Ian Warburton

13

필자의 경우 NSNotificationCenter를 사용하고 인수는 없지만 콜론을 추가하는 선택기를 사용하려고했습니다. 콜론을 제거하면 문제가 해결되었습니다.

선택기 이름을 사용할 때 인수가 없으면 후미 콜론을 사용하지 마십시오. 하나의 인수가 있으면 하나의 후행 콜론을 사용하십시오. 인수가 둘 이상인 경우 각 인수마다 후행 콜론과 함께 이름을 지정해야합니다.

Adam Rosenfield의 답변을 참조하십시오 : Objective-C의 선택기?


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


튜토리얼을
— 따르고이

6

이것의 가장 명백한 원인 (완전성을 위해 포함됨)은 포인터를 부적절하게 캐스팅하고 잘못된 클래스의 메소드를 호출하는 것입니다.

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

이것은 좋은 힌트입니다-뷰나 데이터 객체를 서브 클래 싱하지 않는 것 (예를 들어 서브 클래스 이름을 추가하지 못함)은 또 다른 방법입니다
— Brad M

4

나도 같은 문제가 있었다.

스토리 보드에서 uibutton을 삭제하고 다시 만들었습니다. 이제 모든 것이 제대로 작동합니다.


3

나는 비슷한 문제가 있었지만 해결책은 약간 달랐다. 필자의 경우 범주를 사용하여 기존 클래스를 확장했습니다 (일부 크기 조정 기능의 경우 UIImage- 관심이있는 경우이 방법 참조 ) * .m 파일을 빌드 대상에 추가하는 것을 잊었습니다. 어리석은 오류이지만 어디에서 볼 때 항상 분명하지는 않습니다. 공유 할 가치가 있다고 생각했습니다 ...


3

UIViewcontroller 클래스 코드 내에서 실수로 "@IBAction func ..."를 지우므로 스토리 보드에서 Reference Outlet이 만들어졌지만 런타임에 처리하는 기능이 있었기 때문에 이런 일이 발생했습니다.

해결 방법은 속성 관리자에서 Outlet 참조를 삭제 한 다음 명령 키를 사용하여 클래스 코드로 드래그하여 다시 생성하는 것입니다.

그것이 도움이되기를 바랍니다!


마찬가지로 버튼이 더 이상 존재하지 않는 기능을 참조했을 때 나에게도 일어났습니다.
— Josh Wolff

2

반환 유형의 IBAction 대신 void를 사용해야한다고 생각합니다. 프로그래밍 방식으로 버튼을 정의했기 때문입니다.


2

또 다른 가능한 해결책 : 링커 인수에 '-ObjC'를 추가하십시오.

전체 설명은 여기 있습니다 : 정적 라이브러리의 Objective-C 범주

요점은 생각합니다 : 범주가 정적으로 링크하는 라이브러리에 범주가 정의되어 있으면 링커가 범주 방법으로 링크하기에 충분히 똑똑하지 않습니다. 위의 플래그는 소스 분석을 기반으로해야하는 것으로 생각되는 것이 아니라 모든 객관적인 C 클래스 및 범주에서 링커를 연결 합니다. (해답을 조정하거나 수정하십시오. 링크 된 언어를 알고 있으므로 여기서 앵무새입니다.)


2

나는 같은 오류가 있었고 다음을 발견했다.

코드를 사용할 때

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

또한 최신 Mac OSX 버전으로 업그레이드 할 수없는 구형 Mac에서 Stanford iOS 과정을 진행하고 있습니다. 그래서 나는 여전히 iOS 6.1을 구축하고 있으며, 이것은 나에게 문제를 해결했다.


2

내 경우에는 2 시간 후에 문제를 해결했습니다.

발신자 (tabBar 항목) 에 참조 콘센트가 없습니다 . 그래서 아무데도 가리 키지 않았습니다.

Juste 참조 콘센트 생성 함수에 해당합니다.

이것이 여러분에게 도움이되기를 바랍니다.


추가하기 위해 내 경우에는 IBAction스위프트 로 포트하는 것을 잊었습니다 . 그래서 그 함수를 호출하고 싶지만 찾을 수 없다는 불만이있었습니다.
— DevNebulae

1

저는 현재 iOS 개발을 배우고 있으며 aPress의 "iOS6 개발 시작"책을 살펴보고 있습니다. 10 장 : 스토리 보드에서 동일한 오류가 발생했습니다.

그것을 알아내는 데 이틀이 걸렸지 만 실수로 TableView 셀의 태그를 1로 설정하지 않아야한다는 것을 알았습니다. 이 책을하는 다른 사람에게 비슷한 오류가 발생하면 도움이 되었기를 바랍니다.

내 코드의 미래 오류를 쉽게 찾을 수 있기를 바랍니다. 하하하 디버그 오류는 올바른 방향으로 나를 알아내는 데 아무런 도움이되지 않았습니다 (또는 적어도 디버거를 이해하기에는 너무 새롭습니다, lol).


1

필자의 경우 UIWebView를 사용하고 NSURL 대신 두 번째 매개 변수에 NSString을 전달했습니다. 따라서 잘못된 클래스 유형이 함수에 전달되면이 오류가 발생할 수 있다고 생각합니다.


1

.. 그리고 이제 내꺼

다른 버튼의 매개 변수에 액세스하는 메소드에 버튼이 연결되어 있고 버튼 자체로 무언가를 시도하자마자 큰 효과가 있었지만 충돌이 발생했습니다. 컴파일하는 동안 오류가 표시되지 않았습니다. 솔루션?

버튼을 파일 소유자에게 연결하지 못했습니다. 그래서 여기 누군가 나처럼 바보라면, 이것을 시도하십시오 :)


1

또 다른 약간의 솔루션 / 케이스.

Xamarin과 MvvmCross를 사용하고 있으며 UIButton을 ViewModel에 바인딩하려고했습니다. UIButton을 Outlet과 TouchUpInside에 연결했습니다.

바인딩 할 때 콘센트 만 사용합니다.

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

XCode에서 작업 (TouchUpInside) 연결을 제거하기 만하면 해결되었습니다.

추신 : 이것은 이전 답변과 특히 @Chris Kaminski와 관련된 모든 것이 기본이지만, 이것이 누군가를 돕기를 바랍니다 ...

건배.


1

나는 같은 문제가 있었다. 문제는 하나의 버튼에 두 가지 동작 방법이 있다는 것입니다. 내가 한 것은 내 버튼에 대한 첫 번째 작업 방법을 만든 다음보기 컨트롤러에서 삭제했지만 연결 관리자의 기본 스토리 보드에서 연결을 끊는 것을 잊었습니다. 두 번째 조치 방법을 추가했을 때 하나의 버튼에 대해 두 가지 조치 방법이 있었으므로 오류가 발생했습니다.


1

나를 위해, 그것은 interfacebuilder bij ctrl-dragging에서 생성 된 남은 연결이었습니다. 끊어진 연결 이름은 오류 로그에있었습니다

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

버튼에 연결된 작업이있었습니다. 콘센트가 더 이상 내 코드에 없기 때문에 버튼을 누르면 앱이 다운되었습니다. 로그에서 이름을 검색하면 스토리 보드에서 이름이 표시되었습니다. 그것을 삭제하고 충돌이 사라졌습니다!


0

사용자 "oli206"과 마찬가지로 스탠포드 iOS 클래스 C193P도 사용했기 때문에 Leonard Challis에게 답장을 보냅니다.

"잡히지 않은 예외 'NSInvalidArgumentException'으로 인해 앱을 종료하는 이유 :"

문제는 계산기의 "Enter"버튼이 두 번 연결되어 있고 친구가 스토리 보드에서 버튼을 검사 한 결과 마우스 오른쪽 버튼을 클릭했을 때 "Touch Up Inside"속성에 2 개의 항목이 있음을 알았습니다. "Enter"버튼. "Touch Up Inside" "Sent Events"중 하나를 지우면 문제가 해결되었습니다.

이는 2 개의 전송 된 이벤트 (문제 중 하나가 예외를 발생 시켰음)로 문제가 발생했음을 나타냅니다 (지정 1의 계산기 연습에서 C193P 비디오 클래스의 경우).


나는 어떻게 3 항목을 가지고 있었다. :)
— 1.21 기가 와트

0

InterfaceBuilder의 ViewControllerScene에 ViewController를 할당하지 않으면 발생할 수 있습니다. 따라서 ViewController.m은 어떤 장면에도 연결되어 있지 않습니다.



0

이것의 또 다른 어리석은 원인은 인터페이스 (.h)에 선택기가 정의되어 있지만 구현 (.m)에는 없습니다 (pe typo)


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에서는 그렇지 않았으며 다른 장치에 정확히 동일한 빌드를 배포 한 경우에도 마찬가지였습니다.

어쨌든 컴파일러가 왜 이것을 말하지 않는지 모르겠습니다. 문제는 솔직합니다.


0

ControllerA 클래스에서 사용자 정의 ControllerB 클래스 내의 공용 속성으로 속성을 설정하려고하지만 스토리 보드의 ID 관리자에서 아직 "사용자 정의 클래스"를 설정하지 않은 경우에도 이러한 상황이 발생할 수 있습니다.


0

내 문제와 해결책은 달랐으며 미래 독자들이 머리를 두드리지 않고 벽에 저장할 수 있도록 여기에 게시해야한다고 생각했습니다.

동일한 UIVIewController에 다른 xib를 할당하고 어디서나 검색 한 후에도 수정 방법을 찾을 수 없었습니다. 그런 다음 전화를 걸었던 AppDelegate를 확인 initWithNibName하고 코드를 복사하는 동안 xib 이름을 변경했지만 UIViewController클래스 변경을 잊어 버렸습니다 . 따라서 어떤 해결책도 도움이되지 않으면 initWithNibName방법을 확인하십시오 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.