#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를 사용하는 대표적인 예
- 사용자 이벤트(버튼)
- 타이머
- 알림