스위프트 자체 는 선택기를 사용하지 않습니다. Objective-C에서 선택기를 사용하는 여러 디자인 패턴이 스위프트에서 다르게 작동합니다. (예를 들어, 프로토콜 유형 또는 is
/ as
테스트 대신 선택적 체인을 respondsToSelector:
사용 performSelector:
하고 더 나은 유형 / 메모리 안전 을 위해 가능한 경우 클로저를 사용하십시오 .)
그러나 타이머와 타겟 / 액션 패턴을 포함하여 선택기를 사용하는 중요한 ObjC 기반 API가 여전히 많이 있습니다. Swift는 Selector
이러한 작업을위한 유형을 제공합니다 . (Swift는 ObjC SEL
유형 대신 이것을 자동으로 사용 합니다.)
Swift 2.2 (Xcode 7.3) 이상 (Swift 3 / Xcode 8 및 Swift 4 / Xcode 9 포함) :
표현식을 Selector
사용하여 Swift 함수 유형에서을 구성 할 수 있습니다 #selector
.
let timer = Timer(timeInterval: 1, target: object,
selector: #selector(MyClass.test),
userInfo: nil, repeats: false)
button.addTarget(object, action: #selector(MyClass.buttonTapped),
for: .touchUpInside)
view.perform(#selector(UIView.insertSubview(_:aboveSubview:)),
with: button, with: otherButton)
이 방법에 대한 좋은 점은? 함수 참조는 Swift 컴파일러에 의해 확인되므로 #selector
실제로 존재하며 선택 자로 사용할 수있는 클래스 / 메소드 쌍에서만 표현식을 사용할 수 있습니다 (아래 "선택기 가용성"참조). 또한 함수 유형 이름 지정에 대한 Swift 2.2+ 규칙에 따라 필요한만큼만 함수 참조를 자유롭게 작성할 수 있습니다 .
(이것은 @selector()
컴파일러의 -Wundeclared-selector
검사가 명명 된 선택기가 존재하는지 확인 하기 때문에 실제로 ObjC의 지시문에 비해 개선 된 것입니다. 스위프트 함수 참조 #selector
는 존재, 클래스 멤버쉽 및 유형 서명 을 검사 하기 위해 전달합니다 .)
#selector
표현식에 전달하는 함수 참조에 대한 몇 가지 추가 경고가 있습니다 .
- 기본 이름이 동일한 여러 함수 는 함수 참조에 대해 위에서 언급 한 구문을 사용하여 매개 변수 레이블로 구별 할 수 있습니다 (예 :
insertSubview(_:at:)
vs insertSubview(_:aboveSubview:)
). 그러나 함수에 매개 변수가없는 경우이를 명확히하는 유일한 방법 as
은 함수의 형식 서명 (예 : foo as () -> ()
vs foo(_:)
)이 있는 캐스트 를 사용하는 것입니다 .
- Swift 3.0+에는 속성 getter / setter 쌍에 대한 특별한 구문이 있습니다. 예를 들어, 주어진
var foo: Int
경우 #selector(getter: MyClass.foo)
또는 을 사용할 수 있습니다 #selector(setter: MyClass.foo)
.
일반 사항 :
사례 #selector
연구 및 명명을하지 않습니다는 : 때때로 당신은 (동적 ObjC 런타임에 등록 된 방법으로, 예를 들어)와 선택기를 만들 수있는 함수 참조가 없습니다. 이 경우 Selector
문자열에서 from을 구성 할 수 있습니다 . 예를 들어 Selector("dynamicMethod:")
— 컴파일러의 유효성 검사를 잃어 버립니다. 그렇게 할 때 :
각 매개 변수에 콜론 ( )을 포함하여 ObjC 이름 지정 규칙을 따라야 합니다.
선택기 가용성 : 선택기에서 참조하는 메소드는 ObjC 런타임에 노출되어야합니다. Swift 4에서 ObjC에 노출 된 모든 메소드에는 @objc
속성 앞에 선언이 있어야 합니다. (이전 버전에서는 경우에 따라 해당 속성이 무료로 제공되었지만 이제는 명시 적으로 선언해야합니다.)
private
심볼도 런타임에 노출되지 않는다는 점에 유의 하십시오. 메소드에는 최소한 internal
가시성 이 있어야 합니다.
주요 경로 : 이들은 선택자와 관련되어 있지만 동일하지는 않습니다. Swift 3에는 특별한 구문이 chris.valueForKeyPath(#keyPath(Person.friends.firstName))
있습니다. 자세한 내용은 SE-0062 를 참조하십시오. KeyPath
Swift 4 에서는 훨씬 더 많은 것들이 있으므로 적절한 경우 선택기 대신 올바른 KeyPath 기반 API를 사용하고 있는지 확인하십시오.
당신은 아래 선택기에 대한 자세한 읽을 수 오브젝티브 C API를 상호 작용 에 코코아 및 목표 - C와 스위프트를 사용 .
참고 : Swift 2.2 이전에는을 Selector
준수 StringLiteralConvertible
하므로 베어 문자열이 선택기를 사용하는 API로 전달되는 오래된 코드를 찾을 수 있습니다. Xcode에서 "현재 스위프트 구문으로 변환"을 실행하여을 사용하는 사용자를 얻으십시오 #selector
.
selector: test()
호출test
하고 반환 값을selector
인수에 전달합니다.