비'@objc' 메서드가 '@objc' 프로토콜의 선택적 요구 사항을 충족하지 않습니다.
개요:
- 나는 Objective-C 옵션 기능 중 하나의 기본 구현을 제공하는 프로토콜 P1을 가지고 있습니다.
- 옵션 기능의 기본 구현을 제공하면 경고가 표시됩니다.
컴파일러 경고:
Non-'@objc' method 'presentationController(_:viewControllerForAdaptivePresentationStyle:)' does not satisfy optional requirement of '@objc' protocol 'UIAdaptivePresentationControllerDelegate'
버전:
- 스위프트: 3
- Xcode: 8(공개 릴리스)
시도 횟수:
- 가시도를 추가해 .
@objc
하지만 도움이 되지 않습니다.
질문:.
- 어떻게 해결해야 합니까?
- 주변에 일거리가 있습니까?
코드:
@objc protocol P1 : UIAdaptivePresentationControllerDelegate {
}
extension P1 where Self : UIViewController {
func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
return UIViewController()
}
}
class A : UIViewController, P1 {
}
제가 당신의 질문에 대답할 수 있다고 생각하지만, 그것은 당신이 좋아할 만한 대답이 아닙니다.
TL;DR: @objc
함수가 현재 프로토콜 확장에 없을 수 있습니다.대신 기본 클래스를 만들 수 있지만, 이 방법은 이상적이지 않습니다.
프로토콜 확장 및 목표-C
첫째, 이 질문/답변(Can Swift Method Defined on Extensions on Protocols in Objective-c)은 프로토콜 확장이 후드 아래에 배치되는 방식 때문에 프로토콜 확장에 선언된 메소드를 볼 수 없음을 시사하는 것 같습니다.objc_msgSend()
함수이므로 Objective-C 코드에는 표시되지 않습니다. 확장서정려-C에야표-C어시따하)에 표시되어야 하기 입니다.UIKit
사용할 수 있음), 포함하지 않은 것에 대해 소리칩니다.@objc
하지만 일단 당신이 그것을 포함하면, 그것은 당신에게 소리칩니다. 왜냐하면@objc
프로토콜 확장에는 사용할 수 없습니다.이는 프로토콜 확장이 현재 Objective-C에 표시되지 않기 때문일 수 있습니다.
추가하면 오류 메시지가 표시되는 것도 확인할 수 있습니다.@objc
states "@objc는 클래스의 멤버, @objc 프로토콜 및 클래스의 구체적인 확장과 함께만 사용할 수 있습니다.이것은 클래스가 아닙니다. @objc 프로토콜에 대한 확장은 프로토콜 정의 자체(즉, 요구 사항에서)에 있는 것과 같지 않으며, "구체적"이라는 단어는 프로토콜 확장이 구체적인 클래스 확장으로 계산되지 않음을 시사합니다.
해결 방법
안타깝게도 기본 구현이 Objective-C 프레임워크에 표시되어야 하는 경우 프로토콜 확장을 사용할 수 없습니다.저는 아마 처에는, 나음라고 했습니다.@objc
할 수 (사용자가 가컴파적사유클보고장수할래라없스형허다않니기때습확았고용서불지하구되도장에문프에로콜음에토지했특정이용가자히별일합러한사▁swift▁(▁would▁haveally▁specified).UIViewController
. 그래서 저는.class
에한요에 요구 사항P1
이것은 작동하지 않았습니다.
여기서 유일한 해결 방법은 프로토콜 대신 기본 클래스를 사용하는 것이지만 클래스가 단일 기본 클래스만 가질 수 있지만 여러 프로토콜을 준수할 수 있기 때문에 완전히 이상적이지는 않습니다.
이 경로를 선택하는 경우 이 질문(Swift 3 ObjC Optional Protocol Method Not Called in Subclass)을 고려하십시오.Swift 3의 또 다른 현재 문제는 하위 클래스가 슈퍼 클래스의 선택적 프로토콜 요구 사항 구현을 자동으로 상속하지 않는다는 것입니다.이 질문에 대한 대답은 다음과 같은 특수한 방식을 사용합니다.@objc
그 일을 피하기 위해서요.
문제 보고
스위프트 오픈 소스 프로젝트를 수행하는 사람들 사이에서 이미 이 문제가 논의되고 있다고 생각하지만, 결국 스위프트 코어 팀이나 스위프트의 버그 리포터에 도달할 가능성이 높은 애플의 버그 리포터를 사용함으로써 그들이 알고 있다는 것을 확신할 수 있습니다.그러나 이들 중 하나는 버그가 너무 광범위하거나 이미 알려진 것일 수 있습니다.Swift 팀은 또한 사용자가 원하는 새로운 언어 기능을 고려할 수 있으며, 이 경우 먼저 메일 목록을 확인해야 합니다.
갱신하다
2016년 12월 스위프트 커뮤니티에 이 문제가 보고되었습니다.문제가 중간 우선 순위로 여전히 열려 있는 것으로 표시되지만 다음 설명이 추가되었습니다.
이것은 의도된 것입니다.확장이 프로토콜 준수 후에 추가될 수 있기 때문에 모든 채택자에게 이 방법의 구현을 추가할 수 있는 방법은 없습니다.하지만 확장이 프로토콜과 동일한 모듈에 있다면 허용할 수 있을 것 같습니다.
그러나 프로토콜이 확장자와 동일한 모듈에 있으므로 향후 버전의 Swift에서 이 작업을 수행할 수 있습니다.
업데이트 2
2017년 2월, Swift Core Team 멤버 중 한 명이 다음과 같은 메시지와 함께 이 문제를 "Won't Do"로 공식 종료했습니다.
이것은 의도적인 것입니다. 프로토콜 확장은 Objective-C 런타임의 제한으로 인해 @objc 진입점을 도입할 수 없습니다.@objc 진입점을 NSObject에 추가하려면 NSObject를 확장합니다.
장NSObject
아니 심지어는UIViewController
당신이 원하는 것을 정확히 성취하지는 못하겠지만, 불행히도 그것이 가능해질 것 같지는 않습니다.
(매우) 장기적인 미래에, 우리는 다음과 같은 것에 대한 의존을 없앨 수 있을 것입니다.@objc
코코아 프레임워크가 현재 Swift로 작성되지 않았기 때문에 (그리고 안정적인 ABI를 가질 때까지는 그럴 수 없기 때문에) 그 시간은 곧 오지 않을 것입니다.
업데이트 3
Swift에서 더 프레임워크가 있습니다. 2019년 가을부터 Swift에서 Apple이 작성되었습니다.예를 들어 다음을 사용하는 경우SwiftUI
에 UIKit
당신이 문제를 완전히 회피하는 이유는@objc
를 언급할 때 절대 필요하지 않을 것입니다.SwiftUI
방법.
Swift로 작성된 Apple 프레임워크는 다음과 같습니다.
- 스위프트 UI
- 리얼리티 키트
- 결합하다
- 크립토 키트
Swift가 공식적으로 ABI이고 모듈이 안정적인 상태이기 때문에 Swift 5.0과 5.1을 기준으로 이 패턴은 시간이 지남에 따라 계속될 것으로 예상할 수 있습니다.
제가 사용하는 빠른 프레임워크에서 '모듈 안정성'('배포용 라이브러리 빌드' 켜기)을 활성화한 후 이 문제에 부딪혔습니다.
제가 가진 것은 다음과 같습니다.
class AwesomeClass: LessAwesomeClass {
...
}
extension AwesomeClass: GreatDelegate {
func niceDelegateFunc() {
}
}
확장의 함수에 다음 오류가 있습니다.
'LessAwesomeClass'의 하위 클래스를 확장하는 '@objc' 인스턴스 메서드에는 iOS 13.0.0이 필요합니다.
비'@objc' 메서드 'niceDelegate'Func'가 '@objc' 프로토콜 'GreatDelegate'의 요구 사항을 충족하지 않습니다.
확장이 아닌 클래스로 함수를 이동하면 문제가 해결되었습니다.
여기 또 다른 해결 방법이 있습니다.저도 이 문제에 부딪혀서 UIKit에서 Swift로 전환할 수 없습니다.UI 아직.기본 구현을 공통 기본 클래스로 이동하는 것도 저에게는 선택사항이 아니었습니다.기본 구현이 상당히 광범위했기 때문에 코드를 모두 복제하고 싶지 않았습니다.제가 사용하게 된 해결 방법은 프로토콜에서 래퍼 함수를 사용한 다음 각 클래스의 함수를 호출하는 것이었습니다.예쁘지는 않지만 상황에 따라 대안보다는 나을 수도 있습니다.그러면 코드는 다음과 같이 나타납니다.
@objc protocol P1 : UIAdaptivePresentationControllerDelegate {
}
extension P1 where Self : UIViewController {
func wrapPresentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
return UIViewController()
}
}
class A : UIViewController, P1 {
func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
return wrapPresentationController(controller, viewControllerForAdaptivePresentationStyle: style)
}
}
언급URL : https://stackoverflow.com/questions/39487168/non-objc-method-does-not-satisfy-optional-requirement-of-objc-protocol
'sourcecode' 카테고리의 다른 글
mysql에 대한 도커의 액세스 권한 (0) | 2023.09.01 |
---|---|
시스템 유휴 시간 가져오기 (0) | 2023.09.01 |
웹 워커로부터 AJAX 요청을 할 수 있습니까? (0) | 2023.09.01 |
Angular2 동적 변경 CSS 속성 (0) | 2023.09.01 |
평평하지 않은 인덱스를 반환하는 numpy 배열의 Argmax (0) | 2023.09.01 |