[iOS] #selector와 @objc

HYES00·2023년 3월 2일

iOS

목록 보기
1/1

#selectror와 @objc를 알아보자🔥

NotificationCenter.default.addObserver(
      self,
      selector: #selector(editDiaryNotification(_:)),
      name: NSNotification.Name("editDiary"),
      object: nil
    )
  @objc func editDiaryNotification(_ notification: Notification) {
    guard let diary = notification.object as? Diary else { return }
    guard let index = self.diaryList.firstIndex(where: { $0.uuidString == diary.uuidString }) else { return }
    self.diaryList[index] = diary
    self.diaryList = self.diaryList.sorted(by: {
      $0.date.compare($1.date) == .orderedDescending
    })
    self.collectionView.reloadData()
  }

NotificationCenter을 사용하던 중 #selector을 만나게 되었고 이와 더불어 @objc도 만나게 되었어요. 도대체 이 둘이 뭔지 알아보도록 하겠습니다.

#selector

selector는 개체에 대해 실행할 메서드를 선택하는 데 사용되는 이름이거나 소스코드가 컴파일 될 때 이름을 대체하는 고유 식별자이다. selector 자체는 하는 게 없고 "그냥 식별자"이다.
objective0-C 시절 특정 메서드를 컴파일 타입에 동적으로 식별하고 참조하는 역할을 했다.

swift를 사용하는 지금은 이런 별도의 객체를 사용하지 않아도 메서드를 동적으로 동작시킬 수 있기 때문에 직접적으로 selector를 필요로 하지 않는다.

하지만 여전히 많은 iOS API들이 Objective-C를 기반으로 동작을 하며 Objective-C에 의존하여 돌아간다. 그렇기 떄문에 Swift에서 직접적으로 Selector를 사용하지는 않지만 Objective-C의 selector와 유사한 기능을 하는 Selector를 필요로 한 것이다.

그렇다면 @objc는 왜 쓸까?

컴파일 타임에 메서드를 바인딩하는 Swift와 달리 Objective-C는 런타임에 메서드를 바인딩한다. 따라서 Swift에서 Objective-C에 의존적인 메서드를 사용할 때는 해당 메서드가 Objective-C와 유사한 방식으로 컴파일 되어야함을 컴파일러에게 알려줘야 하고 이를 의미하는 것이 @objc이다. 이를 메서드 앞에 붙여주면 Swift로 작성된 코드를 Objective-C 런타임에서도 사용할 수 있게 된다.

결론은

selector는 메서드를 식별할 수 있는 고유한 이름이며 UIKit 내부의 Objective-C 런타임으로 실행되는 메서드가 셀렉터를 파라미터로 전달받을 때, 전달에 필요한 셀렉터 인스턴스를 생성하려고 사용한다.

Swift에서 Objective-C 기반으로 동작하는 iOS API를 사용할 때, selector는 식별자 역할이며 동적으로 함수를 동작시키고 @objc키워드를 붙여 Objective-C와 유사한 방식으로 컴파일 되어야함을 알려준다.

profile
이제라도 기록하자🙌🏻

0개의 댓글