Objective-C를 사용하여 런타임에 선택기를 어떻게 동적으로 만들 수 있습니까?


93

을 사용하여 SEL컴파일 타임에 를 만드는 방법을 알고 @selector(MyMethodName:)있지만 NSString. 이것이 가능할까요?

내가 할 수있는 것:

SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];

내가 원하는 것 : (의사 코드, 이것은 분명히 작동하지 않습니다)

SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];

Apple API 문서를 검색했지만 컴파일 시간 @selector(myTarget:)구문 에 의존하지 않는 방법을 찾지 못했습니다 .

답변:


180

저는 Objective-C 프로그래머가 아니라 단순히 동조자이지만 NSSelectorFromString 이 필요할 수도 있습니다. 런타임 참조 에서 문자열을 선택 자로 변환하는 데 사용할 수 있다는 것이 명시 적으로 언급되어 있습니다.


5
Google-fu에 대해 좀 더 알아 보겠습니다. 그게 바로 제가 찾고 있던 (또는 그렇지 않은) 것입니다.
craigb

글쎄요, 며칠 전에 Objective-C 2.0 문서를 읽었 기 때문에 여전히 북마크에 링크가 있습니다.
Torsten Marek

40

XCode 문서에 따르면 의사 코드가 기본적으로 올바르게 작동합니다.

@selector () 지시문을 사용하여 컴파일 타임에 SEL 변수에 값을 할당하는 것이 가장 효율적입니다. 그러나 어떤 경우에는 프로그램이 런타임에 문자열을 선택기로 변환해야 할 수도 있습니다. 이것은 NSSelectorFromString 함수로 수행 할 수 있습니다.

setWidthHeight = NSSelectorFromString(aBuffer);

편집 : 부머, 너무 느립니다. :피


2
NSStringFromSelector(@"doWork")변환 그것을 다른 방법 (단지 참고하시기 바랍니다)
bendytree

8
내 생각에는 NSStringFromSelector (@selector (doWork))
jpswain

그리고 그 선택자는 무엇을할까요? 블록이나 무언가를 지정해야하지 않습니까?
user4951 2011

12

이전 응답자의 답변이 제안하는 것보다 조금 더 복잡 하다고 말해야합니다. 정말로 선택자를 만들고 싶다면 ... "둘러서있는" "전화 하나"가 아니라 .. .

"new"메서드에 의해 호출 될 함수 포인터를 만들어야합니다. .. 같은 메서드의 경우 다음과 같이 [self theMethod:(id)methodArg];작성합니다.

void (^impBlock)(id,id) = ^(id _self, id methodArg) { 
     [_self doSomethingWith:methodArg]; 
};

그런 다음 IMP블록을 동적으로 생성해야합니다. 이번에는 "self", the SEL및 모든 인수를 전달합니다.

void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock);

전체 빨판에 대한 정확한 메서드 서명과 함께 클래스에 추가합니다 (이 경우 "v@:@", void return, object caller, object argument).

 class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");

여기 내 저장소 중 하나에서 이러한 종류의 런타임 헛소리에 대한 좋은 예를 볼 수 있습니다 .


5

오래 전에 답변을 받았지만 여전히 공유하고 싶습니다. 이것은 다음을 사용하여 수행 할 수 있습니다.sel_registerName .

질문의 예제 코드는 다음과 같이 다시 작성할 수 있습니다.

SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];

2
실제로 NSSelectorFromString@ torsten-marek이 언급 한 sel_registerName것은 후드 아래에서 사용 합니다. appledev : "NSSelectorFromString은 aSelectorName의 UTF-8 인코딩 문자 표현을 sel_registerName에 전달하고 해당 함수에서 반환 한 값을 반환합니다."
PLG
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.