programing

Swift #selector 구문으로 컴파일 오류의 "모호한 사용"을 해결하려면 어떻게 해야 합니까?

instargram 2023. 9. 14. 21:37
반응형

Swift #selector 구문으로 컴파일 오류의 "모호한 사용"을 해결하려면 어떻게 해야 합니까?

[참고 이 질문은 원래 Swift 2.2에서 작성되었습니다.Swift 4용으로 개정되었으며, 두 가지 중요한 언어 변경이 포함되어 있습니다. 첫 번째 메서드 매개 변수 외부는 더 이상 자동으로 억제되지 않으며 선택기는 Objective-C에 명시적으로 노출되어야 합니다.]

우리 반에 이 두 가지 방법이 있다고 치자.

@objc func test() {}
@objc func test(_ sender:AnyObject?) {}

이제 스위프트 2.2의 새로운 제품을 사용하고 싶습니다.#selector이 방법들 중 첫 번째 방법에 해당하는 선택기를 만들기 위한 구문,func test()해야 합니까?제가 그걸 어떻게 합니까?시도해 볼 때:

let selector = #selector(test) // error

사용이라는 합니다. "모호한 사용"이라는 오류가 발생합니다.test()." 하지만 내가 이렇게 말한다면,

let selector = #selector(test(_:)) // ok, but...

... 오류는 사라지지만 잘못된 방법, 매개 변수가 있는 방법을 언급합니다.파라미터가 없는 을 참고하고 싶습니다.제가 그걸 어떻게 합니까?

[참고: 이 예는 인위적인 것이 아닙니다.에는 Objective-CSObject표-CΩ두가 .copy그리고.copy: 메서드,스,트copy()그리고.copy(sender:AnyObject?)할 수 함.];에서 가 할 할 에서 가

[참고 이 답변은 원래 Swift 2.2에서 작성되었습니다.Swift 4용으로 개정되었으며, 두 가지 중요한 언어 변경이 포함되어 있습니다. 첫 번째 메서드 매개 변수 외부는 더 이상 자동으로 억제되지 않으며 선택기는 Objective-C에 명시적으로 노출되어야 합니다.]

함수 참조를 올바른 메서드 서명에 캐스팅하여 이 문제를 해결할 수 있습니다.

let selector = #selector(test as () -> Void)

(하지만, 제 생각에는 이렇게 하지 않으셔도 됩니다.저는 이 상황을 버그로 간주하여 스위프트가 함수를 참조하는 구문이 부적절하다는 것을 밝힙니다.버그 신고를 했지만 소용이 없었습니다.)


나온 를 간단히 .#selector구문:

이 구문의 목적은 선택기를 리터럴 문자열로 제공할 때 발생할 수 있는 너무 일반적인 런타임 충돌(일반적으로 "인식되지 않는 선택기")을 방지하는 것입니다.#selector()함수 참조를 가져오면 컴파일러가 함수가 실제로 존재하는지 확인하고 Objective-C 셀렉터에 대한 참조를 해결합니다.그러므로, 당신은 어떤 실수도 쉽게 저지를 수 없습니다.

(편집: 네, 가능합니다.완전한 빈 머리가 될 수 있으며 대상을 에 의해 지정된 작업 메시지를 구현하지 않는 인스턴스로 설정할 수 있습니다.#selector당신은입니다. 컴파일러는 당신을 막지 못할 것이고 당신은 옛날처럼 추락할 것입니다. 하아...

함수 참조는 세 가지 형태 중 하나로 나타날 수 있습니다.

  • 함수의 맨 이름입니다.함수가 모호하지 않으면 충분합니다.따라서 예를 들어 다음과 같습니다.

    @objc func test(_ sender:AnyObject?) {}
    func makeSelector() {
        let selector = #selector(test)
    }
    

    밖에는 .test 그래서 이드,서거#selector개도다가ta도sotn개esdrh#selector매개 변수는 언급하지 않았습니다. [Objective-C] 및 [Objective-C]가 ."test:"(콜론을 사용하여 파라미터를 나타냄).

  • 나머지 서명과 함께 함수의 이름입니다.예를 들어,

    func test() {}
    func test(_ sender:AnyObject?) {}
    func makeSelector() {
        let selector = #selector(test(_:))
    }
    

    는 2개의 의 2파운드가 있습니다.testmethods,; 방법들,서는할가다법다;법가s는,할서test(_:)매개 변수가 있는 두 번째 매개 변수로 분해됩니다.

  • 나머지 서명이 있거나 없는 함수의 이름과 매개 변수의 유형을 표시하는 캐스트.따라서:

    @objc func test(_ integer:Int) {}
    @nonobjc func test(_ string:String) {}
    func makeSelector() {
        let selector1 = #selector(test as (Int) -> Void)
        // or:
        let selector2 = #selector(test(_:) as (Int) -> Void)
    }
    

    여기, 오버로드가 발생했습니다. test(_:). 오버로드는 Objective-C에 노출될 수 없습니다. Objective-C는 오버로드를 허용하지 않기 때문에 그 중 하나만 노출되고, Selector는 Objective-C 기능이기 때문에 노출된 것에 대해서만 Selector를 구성할 수 있습니다.하지만 스위프트에 관한 한 우리는 여전히 명확하게 밝혀야 하고, 출연진들은 그렇게 합니다.

    (위의 대답의 기초로 사용되는 것은 언어적인 특징입니다. 제 생각에는 잘못 사용된 것 같습니다.)

또한 Swift가 어떤 클래스의 함수인지 알려줌으로써 함수 참조를 해결하도록 도와주어야 할 수도 있습니다.

  • 위로 으로 더 의 해상도가가 에서 하는 의 으로 하지 가 의 에서와 와 하거나 의 하지 에서와 가 의 가 선택적으로 다음과 같이 말할 수 있습니다.self점선로)으로#selector(self.test) 할 에서는 에서는 .

  • 그렇지 않으면 이 실제 예제와 같이 점 표기를 사용하여 메서드가 구현된 인스턴스에 대한 참조를 사용합니다(self.mpmtpx MPMusicPlayerController):

    let pause = UIBarButtonItem(barButtonSystemItem: .pause, 
        target: self.mp, action: #selector(self.mp.pause))
    

    ...또는 클래스 이름을 점선으로 표시하여 사용할 수 있습니다.

    class ClassA : NSObject {
        @objc func test() {}
    }
    class ClassB {
        func makeSelector() {
            let selector = #selector(ClassA.test)
        }
    }
    

    이 말하는 에, 으로 보입니다. 왜냐하면 당신이 말하는 것처럼 보이기 때문입니다.test인스턴스 메소드가 아닌 클래스 메소드이지만 그래도 셀렉터로 올바르게 해결됩니다.)

클래스 외부에서 인스턴스 메서드에 액세스하는 것과 같은 누락된 모호성을 추가합니다.

class Foo {
    @objc func test() {}
    @objc func test(_ sender: AnyObject?) {}
}

, , 의 서명.test()은 ㅇ(Foo) -> () -> Void이 을 이 할 가 입니다 입니다 가 을 이 할 .Selector.

#selector(Foo.test as (Foo) -> () -> Void)
#selector(Foo.test(_:))

할 를 를 참조할 수 .Selector원답에 있는 s 과 과

let foo = Foo()
#selector(foo.test as () -> Void)
#selector(foo.test(_:))

저의 경우(Xcode 11.3.1) 디버깅 중에 lldb를 사용할 때만 오류가 발생하였습니다.실행할 때는 제대로 작동합니다.

언급URL : https://stackoverflow.com/questions/35658334/how-do-i-resolve-ambiguous-use-of-compile-error-with-swift-selector-syntax

반응형