SWIFT

[Swift] #selector(셀렉터)

clamp 2023. 3. 20. 20:40

#selector

메서드 주소를 통해 메서드를 가리키기 위한 기술

 

물론 메서드 주소를 통해 메서드를 호출할 순 없다. 단순하게 메서드를 가리키는 것?

셀렉터는 속성에 접근이나 메서드를 호출하는게 아니다. 가리키기만 한다.

코드 영역의 메모리 주소를 가리켜서, (버튼이 눌렸을 때 해당 메서드를 실행시키기 위해) 연결시키는 기술

 

  • 클래스와 Objective-C 프로토콜에 포함된 멤버에만 적용 가능하다.
  • 구조체는 적용이 불가능하다.
  • 내부적으로 Objective-C프레임워크를 사용하고 있다.
  • @objc 특성을 추가해야지만 사용 가능하다.
#selector( 메서드 )

셀렉터 내부에 메서드를 명시하게되면 해당 메서드를 가리키게 되고 이를 변수에 할당하면 셀렉터 구조체가 생성된다.


소스코드를 통한 이해

class Dog {
    var num = 1.0
    
    @objc var doubleNum: Double {
        get {
            return num * 2.0
        }
        set {
            num = newValue / 2.0
        }
    }
    
    @objc func run() {
        print("강아지가 달립니다.")
    }
}

// (계산)속성을 가르킬때
let eyesSelector = #selector(getter: Dog.doubleNum)
let nameSelector = #selector(setter: Dog.doubleNum)

// 메서드를 가르킬때
let runSelector = #selector(Dog.run)

 

계산속성도 따지고 보면 메서드이므로 계산속성도 가리킬 수 있다.

#selector(getter: Dog.doubleNum) 은 계산속성인 doubleNum의 getter(get)부분을 가리키게 되고, 

#selector(setter: Dog.doubleNum) 은 계산속성인 doubleNum의 setter(set)부분을 가리키게 된다.

 

#selector(Dog.run)은 Dog클래스의 run메서드를 가리키게된다.

 

실제로 셀렉터는 버튼따위를 코드로 구현할 때 action과 연결시키기 위해 많이 사용된다.

 


 

실제 사용 예시( 스토리보드가 아닌 코드로 UI작성과 함수 연결 )

import UIKit

class ViewController: UIViewController {

    // 버튼 관련 속성(변수) 선언 (일단 인스턴스 생성해서 담기)
    let codeButton: UIButton = UIButton(type: .system)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureUI()
    }
    
    // 코드로 짜는 UI관련 함수
    func configureUI() {
        // 버튼 셋팅
        codeButton.setTitle("Code Button", for: .normal)
        codeButton.setTitleColor(.white, for: .normal)
        codeButton.backgroundColor = .blue
        // 자동 제약 잡아주는 것 취소 ===> 코드로 오토레이아웃 잡으려면 필수
        codeButton.translatesAutoresizingMaskIntoConstraints = false
        
        // 버튼 눌렀을때 실행시킬 함수 연결하기 ⭐️⭐️⭐️
        // 아래의 self는 ViewController클래스를 가리킨다. 그러므로 codeButtonTapped으로 생략도 가능하다.
        codeButton.addTarget(self, action: #selector(ViewController.codeButtonTapped), for: .touchUpInside)
        
        
        // 버튼을 화면에 올리기
        view.addSubview(codeButton)
        // 오토레이아웃 코드로 짜기 (지금 중요하지 않음)
        NSLayoutConstraint.activate([
            codeButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            codeButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 30),
            codeButton.widthAnchor.constraint(equalToConstant: 200),
            codeButton.heightAnchor.constraint(equalToConstant: 40)
        ])
        
    }
    
    // 스토리보드의 버튼이 눌렸을 때 실행되는 함수
    @IBAction func storyBoardButtonTapped(_ sender: UIButton) {
        print("스토리보드 버튼 눌림")
    }
    
    // 코드로 만든 버튼이 눌렸을 때 실행되는 함수
    @objc func codeButtonTapped() {
        print("코드 버튼 눌림")
    }


}

 

 

스토리보드로 개발을 할 때에는 @IBAction이라는 키워드로 특정 타입, 메서드라는 것을 명시하여 쉽게 사용할 수 있었다.

 

코드로 개발을 할 때에는 아래처럼 해당 버튼이 실행할 메서드와 버튼을 #selector로 이어줘야한다.

codeButton.addTarget(self, action: #selector(ViewController.codeButtonTapped), for: .touchUpInside)

 

#selector를 사용하는 대표적인 예

  • 사용자 이벤트(버튼)
  • 타이머
  • 알림