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파운드가 있습니다.
test
methods,; 방법들,서는할가다법다;법가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.mp
mtpx 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
'programing' 카테고리의 다른 글
var_graphics를 텍스트 파일에 저장합니다. (0) | 2023.09.14 |
---|---|
윈도우 엣지와 관련하여 팝오버의 X 위치를 기준으로 부트스트랩 팝오버의 위치를 변경? (0) | 2023.09.14 |
여러 열이 있는 오라클 롤업 함수 (0) | 2023.09.14 |
마이크로소프트.ACE.OLEDB.12.0' 공급자가 로컬 시스템(서버)에 등록되어 있지 않습니다. (0) | 2023.09.14 |
신호 처리기에서 OCaml로 래핑된 ZeroMQ 코드 호출 (0) | 2023.09.09 |