Objective-C : 여러 개의 인수가있는 선택자 호출


142

MyClass.m에서 나는 정의했습니다

- (void) myTest: (NSString *) withAString{
    NSLog(@"hi, %@", withAString);
}

MyClass.h의 적절한 선언. 나중에 전화하고 싶어

[self performSelector:@selector(mytest:withAString:) withObject: mystring];

MyClass.m에 있지만 잡히지 않은 예외 'NSInvalidArgumentException'으로 인해 앱 종료 와 유사한 오류가 발생합니다 . 이유 : '* -[MyClass myTest : withAtring :] : 인식 할 수없는 선택기가 인스턴스 0xe421f0에 전송되었습니다'

콘솔에 문자열을 인쇄하는 인수를 사용하지 않고 제대로 작동하는 선택기를 사용하여 간단한 경우를 시도했습니다. 코드에 어떤 문제가 있으며 어떻게 해결할 수 있습니까? 감사.


4
귀하의 게시물은 '다중 인수'에 대해 묻지 만 하나만 사용합니다. 이제 누군가가 배열 / dict / 무엇이든 포장하지 않고 여러 인수로 어떻게 해야하는지 궁금합니다.
RonLugge

답변:


137

메소드 서명은 다음과 같습니다.

- (void) myTest:(NSString *)

withAString이 매개 변수가됩니다 (이름이 잘못되어 선택기 서명의 일부인 것 같습니다).

이런 식으로 함수를 호출하면 :

[self performSelector:@selector(myTest:) withObject:myString];

작동합니다.

그러나 다른 포스터가 제안했듯이 방법의 이름을 바꾸고 싶을 수 있습니다.

- (void)myTestWithAString:(NSString*)aString;

그리고 전화 :

[self performSelector:@selector(myTestWithAString:) withObject:myString];

2
사람들이이 답변을 통해 혜택을 얻은 것을 보았으므로 응답을 검토했습니다. 호출은 간단하게 제안합니다.-(void) testWithString : (NSString *) aString;
Lyndsey Ferguson

313

Objective-C에서 선택 자의 서명은 다음으로 구성됩니다.

  1. 메소드 이름 (이 경우 'myTest'임) (필수)
  2. 메소드에 입력이있는 경우 메소드 이름 뒤에 ':'(콜론).
  3. 모든 추가 입력에 대한 이름과 ':'.

선택기는 다음에 대한 지식이 없습니다.

  1. 입력 유형
  2. 메소드의 리턴 유형

performMethodsViaSelectors 메소드가 선택기로 다른 클래스 메소드를 수행하는 클래스 구현은 다음과 같습니다.

@implementation ClassForSelectors
- (void) fooNoInputs {
    NSLog(@"Does nothing");
}
- (void) fooOneIput:(NSString*) first {
    NSLog(@"Logs %@", first);
}
- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {
    NSLog(@"Logs %@ then %@", first, second);
}
- (void) performMethodsViaSelectors {
    [self performSelector:@selector(fooNoInputs)];
    [self performSelector:@selector(fooOneInput:) withObject:@"first"];
    [self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];
}
@end

선택기를 만들려는 방법에는 단일 입력이 있으므로 다음과 같이 선택기를 만들 수 있습니다.

SEL myTestSelector = @selector(myTest:);

3
좋은 대답입니다. 약간 명확하게 설명하려면 선택자 이름에 매개 변수가 있거나 없을 수있는 부분이 하나 이상 있어야합니다. 매개 변수가 있으면 콜론이 있어야합니다. 둘 이상의 부분이있는 선택기 이름은 각 부분 뒤에 콜론이 있어야합니다. "-useFoo : andBar : toDoSomething"형식의 선택기를 갖는 것은 합법적이지 않습니다.
Quinn Taylor

이것에 감사합니다. 한동안이 문제로 어려움을 겪고 있습니다. 도와 줘서 기쁩니다!
James Hall

입력 매개 변수는 정수는 어떻습니까? 이 경우 어떻게해야합니까?
Hoang Pham

1
NSNumber 객체의 정수를 래핑하고 ( developer.apple.com/library/ios/#documentation/Cocoa/Reference/… 참조 ) 호출 된 메소드의 본문에서 정수 값을 검색해야합니다. 약간 장황 할 수 있지만 (더 나은 방법을 찾지 못했습니다) 잘 작동합니다.
Shane Arney

30
+100 : 대단합니다! 여러 개의 "withObject :"매개 변수를 사용할 수있는 방법을 몰랐습니다. 내가 할 수 있다면 나는 이것을 백 번
찬성

13

@ 셰인 아르 니

performSelector:withObject:withObject:

이 방법은 최대 2 개의 인수를 전달하는 데만 사용되며 지연 될 수 없다고 언급 할 수도 있습니다. (예 : performSelector:withObject:afterDelay:).

사과가 보낼 객체 2 개만 지원하고 좀 더 일반적으로 만들지 않은 것이 이상합니다.


2
정보 주셔서 감사합니다. 나는 일을 지연시킬 수 없었고 지금은 이유를 알고 있습니다. 참고로 두 객체의 한계를 극복하기 위해 배열을 전달한 다음 메소드에서 사용했습니다.
JScarry

7

코드에는 두 가지 문제가 있습니다. 하나는 식별되어 답변되었지만 다른 하나는 그렇지 않았습니다. 첫 번째는 선택기에 매개 변수 이름이 누락되었다는 것입니다. 그러나 수정 한 경우에도 수정 된 메소드 서명에 여전히 둘 이상의 인수가 있다고 가정하면 행에서 여전히 예외가 발생합니다. 수정 된 메소드가 다음과 같이 선언되었다고 가정하십시오.

-(void)myTestWithString:(NSString *)sourceString comparedTo:(NSString *)testString ;

여러 개의 인수를 취하는 메소드에 대한 선택기를 작성하는 것은 완벽합니다 (예 : @selector (myTestWithString : comparedTo :)). 그러나 performSelector 메소드를 사용하면 하나의 값만 myTest에 전달할 수 있습니다. 불행히도 둘 이상의 매개 변수가 있습니다. 오류가 발생하여 충분한 값을 제공하지 않았다고 알려줍니다.

컬렉션의 유일한 매개 변수이므로 컬렉션을 사용하도록 메서드를 항상 재정의 할 수 있습니다.

-(void)myTestWithObjects:(NSDictionary *)testObjects ;

그러나보다 우아한 솔루션이 있습니다 (리팩토링이 필요하지 않음). 대답은 그와 함께있는 NSInvocation를 사용하는 것입니다 setArgument:atIndex:invoke방법.

자세한 내용을 원하면 코드 예제를 포함한 기사를 작성했습니다 . 스레딩에 중점을 두지 만 기본 사항은 여전히 ​​적용됩니다.

행운을 빕니다!


3

메소드 서명이 의미가 없습니다. 오타가 아닌지 확실합니까? 컴파일하는 방법이 확실하지 않지만 무시하고 있다는 경고가 표시됩니까?

이 방법에는 몇 개의 매개 변수가 필요합니까?


당신이 쓰는 죄송합니다. 나는 그것을 입력하고 코드를 복사하여 붙여 넣는 대신 더 간단하게 만들려고했지만 프로세스에서 실수를했습니다. 이 방법이 하나의 매개 변수를 사용하기를 기대합니다. 인쇄하고 싶은 문자열.
Stu

2

클래스가 다음과 같이 정의되어야한다고 생각하십시오.

- (void) myTestWithSomeString:(NSString *) astring{
    NSLog(@"hi, %s", astring);
}

하나의 매개 변수 만 있으므로 단일 매개 변수 만 있어야합니다.

NSLog에 % @를 사용하는 것도 고려해 볼 수 있습니다. 문자열로만 사용하는 것이 아니라 모든 객체를 작성하는 것이 좋습니다.


-1

iOS 사용자는 자동 대문자 화를 기대합니다. 표준 텍스트 필드에서 대소 문자 구분 언어로 된 문장의 첫 문자는 자동으로 대문자로 표시됩니다.

이러한 기능을 구현할지 여부를 결정할 수 있습니다. 방금 나열된 기능에 대한 전용 API가 없으므로이를 제공하는 것이 경쟁 우위입니다.

Apple 문서에 따르면이 기능에 사용할 수있는 API가 없으며 사용자 정의 키보드에 예상되는 다른 기능이 있습니다. 이를 구현하려면 자신의 논리를 찾아야합니다.

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