옵젝시 selector

개요

옵젝시에서 함수를 실행할 때 selector로 실행할 때가 있다.

selector가 뭘까? swift에서는 어떤 개념일까?




selector란?


selector란 함수를 함수명으로 호출하는 것처럼 각각의 메시지는 키워드를 나열한것을 이름처럼 써서 표현한 것이다.

즉 메시지 키워드를 배열한 것이다. 프로그램 속에서 selector는 컴파일 할 때 해당 코드로 변환된다.

이 해당 함수의 코드를 가리키는 자료형을 SEL형이라고 한다. 이 데이터를 컴파일러 지시자 @selector를 이용하여 알려준다.

sel형 변수를 만들 수도 있는데 sel형 변수에 null을 보낼수도 있고 (SEL)0이라고 할 수도 있다.

SEL형 값을 이용해서 메시지 송신도 가능하다. NSObject 메서드 중에서

  • (id) performSelector: (SEL) aSelector : aSelector가 나타내는 메시지를 리시번에 보내고 그 결과를 가져온다.
  • (id) performSelector: (SEL) aSelector withObject: (id) anObject: object를 매개변수로 같이 보낸다.
[target description];
[target performSelector: @selector(description)];
//위의 두 코드는 같은 동작을 한다.

그러나 selector를 사용하면 함수포인터를 사용한 것과 같이 호출되는 메서드를 런타임 시 결정한다.

함수 포인터는 그 함수가 존재하는 메모리 주소를 나타내는 것이다.

Selector를 이용하는 것은 런타임에 메서드가 실행될 때 동적으로 식별하기 위한 이름이라고 할 수 있다.

@selector() 구문을 사용하여 Selector를 생성할 수 있다.

예를 들어, @selector(doSomething)은 doSomething 메서드를 나타내는 Selector를 생성한다.




직접 호출? Selector 호출?



직접 호출


대부분의 상황에서는 직접적으로 메서드를 호출하는 것이 일반적이다.

특정 시점이나 조건에 따라 메서드를 호출하지 않고 코드 흐름상에서 단순히 메서드를 실행할 때는 직접호출한다.

가독성을 위해서 Selector를 사용하지 않아도 되는 경우는 직접호출을 사용한다.



Selector 호출


객체에 메시지를 보내는 것(performSelector: 메소드와 함께 사용)

프로그램 실행 중에 동적으로 메서드를 호출하는 데 사용

인터페이스와 객체 간의 통신을 위해 사용되는 타겟-액션 메커니즘에서 사용

컴파일 시간에 문자열을 통해 메서드의 이름을 찾지 않고, 메서드의 고유한 식별자 역할을 한다. const char * 역할을 하는듯

주로 메인스레드에서 실행된다.




selector 동작 방법


selector는 실행할 메서드의 이름만 가지고 있는 자료형이다.

즉 개념적으로는 const char * ≈ selector라고 할 수 있다. 그러나 실제로 문자열과는 다른 데이터 형식으로 처리된다.

함수포인터와도 헷갈릴 수 있는데 함수포인터는 그 함수의 실행 코드가 있는 위치의 첫 주소값을 가지고있지만 selector는 어디 있는지 모른다.

[self hoho];와 [self performSelector:@selector(hoho)];는 같은 동작을 한다.

직접 호출하면 컴파일 시간에 self를 뒤져서 hoho가 있는 지 확인한다.

해당 함수 코드 위치까지 알 수 있는지는 모르지만 있는지 확인하는 것은 확실하다.

없는 함수를 사용하면 없다고 컴파일 경고가 뜨지만 에러는 런타임에 나는 것으로 봐서

그냥 테이블을 뒤져서 문자열을 비교해보고 있는지 확인만 해보는 것 같다.(확실하지 않음)

그런데 @selector(hoho)는 모른다. 그냥 이름만 알고 있고 런타임에 self를 뒤져서 찾아본다.

실행 시간은 그냥 c언어처럼 순차적으로 실행된다.

delay같이 특정 작업을 추가하는 경우 @selector 키워드를 이용한다.

세부적으로는 다르겠지만 메시지, 셀렉터, 메서드, 함수 의미는 비슷한것같다. 생소해서 그러지




Swift에서의 selector


swift는 함수형 프로그래밍 요소도 가지고 있다.

이는 함수를 일급객체로 사용하여 함수를 대입하고 리턴할 수 있지만 옵젝시는 할 수 없다.

따라서 함수단위로 작업할 수 있도록 selector가 필요했지만 swift에서는 굳이 사용할 필요가 없다.

쓴다면 옵젝시의 타깃 액션 매커니즘 혹은 상호 운용성이 필요한 경우에 사용한다.

button을 누르면 특정 작업을 하는 것 같은 동작을 타깃 액션 매커니즘이라고 한다.