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.