Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save linearhw/f06baf806acf933763ed9e0314fce67c to your computer and use it in GitHub Desktop.
Save linearhw/f06baf806acf933763ed9e0314fce67c to your computer and use it in GitHub Desktop.
Effective Objective-C 42

performSelector 는 GCD나 블록이 나오기 전까진 강력한 기능이었다

SEL selector;
if (/* 어떤 조건 */) {
    selector = @selector(foo);
} else if (/* 다른 어떤 조건*/) {
    selector = @selector(bar);
}

하지만 이렇게 동적으로 바인딩하는 데엔 문제가 있다.

  • 컴파일러는 어떤 selector 가 호출될 지 알 수 없다
  • 따라서 release 를 해야 할 지 말아야 할 지 알 수 없다
  • 그래서 안전한 실행을 위해 release 를 추가하지 않는다 -> memory leak!

또한 반환 타입이 void나 객체 타입 밖에 될 수 없다.
반환 타입이 C 구조체이면 performSelector를 사용할 수 없다.

추가적인 parameter 를 전달할 수 있는 method 도 있다.

- (id) performSelector:(SEL)selector
            withObject:(id)object
- (id) performSelector:(SEL)selector
            withObject:(id)objectA
            withObject:(id)objectB

유용해 보이지만 우선 parameter 는 반드시 id 타입이어야 한다. (int, float 등은 사용 불가)
그리고 최대 parameter 개수가 두 개

특정 스레드에서 지연시켜서 사용할 수 있는 method 도 있다.

- (id) performSelector:(SEL)selector
            withObject:(id)argument
            afterDelay:(NSTimeInterval)delay
- (id) performSelector:(SEL)selector
              onThread:(NSThread *)thread
            withObject:(id)argument
         waitUntilDone:(BOOL)wait

하지만 이땐 최대 parameter 개수가 한 개
그래서 결국 parameter 를 dictionary 에 넣은 다음 나중에 꺼내쓰는 방식을 사용하게 된다.
-> 잠재적인 버그가 생기기 쉽다.

따라서?

  • performSelector 대신 GCD 와 블록을 사용하자
  • 지연 후 실행은 dispatch_after, 다른 스레드에서의 실행은 dispatch_async, dispatch_sync
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment