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

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에 전송되었습니다’

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



답변

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

- (void) myTest:(NSString *)

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

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

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

작동합니다.

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

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

그리고 전화 :

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


답변

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:);


답변

@ 셰인 아르 니

performSelector:withObject:withObject:

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

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


답변

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

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

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

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

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

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

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

행운을 빕니다!


답변

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

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


답변

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

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

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

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


답변

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

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

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