스위프트 4의 #selector()로 @objc 추론 삭제를 처리하려면 어떻게 해야 합니까?
저는 제 프로젝트의 소스 코드를 스위프트 3에서 스위프트 4로 변환하려고 합니다.Xcode가 나에게 주는 경고 중 하나는 내 셀렉터에 관한 것입니다.
예를 들어 다음과 같은 일반 선택기를 사용하여 버튼에 대상을 추가합니다.
button.addTarget(self, action: #selector(self.myAction), for: .touchUpInside)
다음과 같은 경고가 표시됩니다.
'#selector'의 인수는 Swift 4에서 더 이상 사용되지 않는 '@objc' 특성 추론에 의존하는 'ViewController'의 인스턴스 메서드 'myAction()'을 참조합니다.
'@objc'를 추가하여 이 인스턴스 메서드를 Objective-C에 표시합니다.
자, 때리기Fix
오류 메시지에서 내 기능에 다음을 수행합니다.
// before
func myAction() { /* ... */ }
// after
@objc func myAction() { /* ... */ }
다음을 포함하도록 모든 기능의 이름을 바꾸고 싶지는 않습니다.@objc
그럴 필요는 없다고 생각합니다
사용되지 않는 선택기를 처리하려면 어떻게 다시 작성해야 합니다.
관련 질문:
수정은 정확합니다. 선택기가 참조하는 방법을 목표-C에 노출시키기 위해 변경할 수 있는 것은 없습니다.
애초에 이 경고의 모든 이유는 SE-0160의 결과입니다.스위프트 4 이전에는internal
또는 목표-C 이상의 호환 구성원NSObject
상속 계층은 다음과 같이 추론되었습니다.@objc
따라서 Objective-C에 노출되므로 셀렉터를 사용하여 호출할 수 있습니다(특정 셀렉터에 대한 메서드 구현을 조회하려면 Obj-C 런타임이 필요하므로).
그러나 Swift 4에서는 더 이상 그렇지 않습니다.오직 매우 구체적인 선언만이 이제 추론됩니다.@objc
예: 재정의@objc
방법, 구현@objc
다음을 의미하는 특성을 가진 프로토콜 요구사항 및 선언@objc
,예를 들어@IBOutlet
.
위 링크된 제안서에 자세히 설명된 바와 같이, 이것의 배후에 있는 동기는 첫째, 방법 과부하를 방지하기 위한 것입니다.NSObject
동일한 셀렉터로 인해 서로 충돌하는 클래스를 상속합니다.둘째, Obj-C에 노출될 필요가 없는 멤버에 대해 thunk를 생성할 필요가 없어 이진 크기를 줄이는 데 도움이 되며, 셋째, 동적 링크 속도를 향상시킵니다.
구성원을 Obj-C에 노출하려면 다음과 같이 표시해야 합니다.@objc
예:
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: #selector(foo), for: .touchUpInside)
}
@objc func foo() {
// ...
}
}
(마이그레이터는 "임의 추론" 옵션을 선택한 상태에서 실행할 때 선택기를 사용하여 자동으로 이 작업을 수행해야 합니다.)
하려면 Obj-C 려면다사을수용있할다습니음을 .@objc extension
:
@objc extension ViewController {
// both exposed to Obj-C
func foo() {}
func bar() {}
}
될 수 구성원에게 으로 Obj-C로 되지 않는 한).@nonobjc
).
모든 Obj-C 호환 구성원이 Obj-C에 노출되어야 하는 클래스가 있는 경우 클래스를 다음과 같이 표시할 수 있습니다.@objcMembers
:
@objcMembers
class ViewController: UIViewController {
// ...
}
자, 추측할 수 있는 모든 멤버들은.@objc
될 것이다.하지만, 위에서 언급한 회원들이 불필요하게 노출되는 단점을 고려할 때, 모든 회원들이 Obj-C에 노출될 필요가 없는 한, 저는 이것을 하는 것을 추천하지 않을 것입니다.
Apple 공식 문서입니다.선택 도구를 호출하려면 @objc를 사용해야 합니다.
목표-C에서 선택기는 목표-C 방법의 이름을 참조하는 유형입니다.는 Swift 서선 Objective-C로 됩니다.
Selector
▁the▁structure▁be,▁usinged▁can다▁and▁construct를 사용하여 구성할 수 있습니다.#selector
표현.할 수 있는 Objective-C 에할메의선서드택만다를다와 같은 합니다.#selector(MyViewController.tappedButton(sender:))
하려면 "Objective-Cetter" "" 앞에 오는 속성 합니다.getter:
또는setter:
:#selector(getter: MyViewController.myButton)
.
스위프트 4.2의 경우, 당신이 해야 할 일은 할당하는 것뿐입니다.@IBAction
당신의 방법으로 그리고 피하세요.@objc
주석
let tap = UITapGestureRecognizer(target: self, action: #selector(self.cancel))
@IBAction func cancel()
{
self.dismiss(animated: true, completion: nil)
}
이미 다른 답변에서 언급했듯이, 다음을 피할 방법이 없습니다.@objc
셀렉터에 대한 주석입니다.
그러나 OP에 언급된 경고는 다음 단계를 수행하여 침묵할 수 있습니다.
- 빌드 설정으로 이동
- @objc 키워드 검색
- Swift 3 @objc 인터페이스의 값을 다음으로 설정합니다.
Off
아래는 위에서 언급한 단계를 보여주는 스크린샷입니다.
이것이 도움이 되길 바랍니다.
뷰 컨트롤러에 객체 c 멤버가 필요한 경우 뷰 컨트롤러 상단에 @objcMembers를 추가하면 됩니다.코드에 IBAction을 추가하면 이 문제를 피할 수 있습니다.
@IBAction func buttonAction() {
}
이 콘센트를 스토리보드에 연결해야 합니다.
언급URL : https://stackoverflow.com/questions/44390378/how-can-i-deal-with-objc-inference-deprecation-with-selector-in-swift-4
'UFO ET IT' 카테고리의 다른 글
Visual Studio VB에서 영역 축소를 비활성화하거나 모든 영역을 확장하는 방법.NET? (0) | 2023.05.13 |
---|---|
Linux/Unix에서 $PATH를 영구적으로 설정하는 방법 (0) | 2023.05.13 |
시스템 정렬 방법.컬렉션.포괄적인.VB에 나열합니다.그물? (0) | 2023.05.13 |
HashSet과 List의 차이점은 무엇입니까? (0) | 2023.05.13 |
Windows에서 makefile을 실행하는 방법 (0) | 2023.04.08 |