UFO ET IT

스위프트 4의 #selector()로 @objc 추론 삭제를 처리하려면 어떻게 해야 합니까?

ufoet 2023. 5. 13. 20:19
반응형

스위프트 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에 언급된 경고는 다음 단계를 수행하여 침묵할 수 있습니다.

  1. 빌드 설정으로 이동
  2. @objc 키워드 검색
  3. Swift 3 @objc 인터페이스의 값을 다음으로 설정합니다.Off

아래는 위에서 언급한 단계를 보여주는 스크린샷입니다.

"Swift 3 @objc interface" 경고 음소거

이것이 도움이 되길 바랍니다.

뷰 컨트롤러에 객체 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

반응형