programing tip

'@objc'가 아닌 방법은 '@objc'프로토콜의 선택적 요구 사항을 충족하지 않습니다.

itbloger 2020. 9. 12. 09:13
반응형

'@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 {

}

나는 당신의 질문에 대답 할 수 있다고 생각하지만 당신이 좋아할 대답은 아닙니다.

요약 : @objc 기능은 현재 프로토콜 확장에 없을 수 있습니다. 이상적인 솔루션은 아니지만 대신 기본 클래스를 만들 수 있습니다.

프로토콜 확장 및 Objective-C

첫째,이 질문 / 답변 ( Can Swift Method Defined on Extensions on Extensions on Protocols Accessed in Objective-c )은 프로토콜 확장이 내부적으로 전달되는 방식 때문에 프로토콜 확장에서 선언 된 메서드가 objc_msgSend()함수에 표시되지 않음을 시사하는 것 같습니다. 따라서 Objective-C 코드에는 표시되지 않습니다. 확장 프로그램에서 정의하려는 방법은 Objective-C에서 볼 수 있어야하기 때문에 ( UIKit사용할 수 있으므로)를 포함하지 않은 것에 대해 소리를 지르지 @objc만 일단 포함하면 @objc허용되지 않기 때문에 소리를 지 릅니다 . 프로토콜 확장. 이는 프로토콜 확장이 현재 Objective-C에 표시되지 않기 때문일 수 있습니다.

@objc"@objc는 클래스의 멤버, @objc 프로토콜 및 클래스의 구체적인 확장에만 사용할 수 있습니다."라는 상태 를 추가하면 오류 메시지가 표시 됩니다. 이것은 수업이 아닙니다. @objc 프로토콜에 대한 확장은 프로토콜 정의 자체 (예 : 요구 사항)에있는 것과 동일하지 않으며 "concrete"라는 단어는 프로토콜 확장이 구체적인 클래스 확장으로 간주되지 않음을 암시합니다.

해결 방법

불행히도 이것은 기본 구현이 Objective-C 프레임 워크에 표시되어야 할 때 프로토콜 확장을 사용하는 것을 거의 완전히 방지합니다. 처음 @objc에는 Swift Compiler가 형식을 준수하는 클래스가 클래스라는 것을 보장 할 수 없기 때문에 프로토콜 확장에서 허용되지 않는다고 생각했습니다 UIViewController. 그래서 내가 넣어 class에 요구 사항을 P1. 이것은 작동하지 않았습니다.

아마도 유일한 해결 방법은 여기에서 프로토콜 대신 기본 클래스를 사용하는 것입니다.하지만 클래스가 단일 기본 클래스 만 가질 수 있지만 여러 프로토콜을 준수 할 수 있기 때문에 이것은 분명히 완전히 이상적이지는 않습니다.

If you choose to go this route, please take this question (Swift 3 ObjC Optional Protocol Method Not Called in Subclass) into account. It appears that another current issue in Swift 3 is that subclasses do not automatically inherit the optional protocol requirement implementations of their superclass. The answer to that questions uses a special adaption of @objc to get around it.

Reporting the Issue

I think this is being discussed already among those working on the Swift open source projects, but you could be sure they are aware by either using Apple's Bug Reporter, which would likely eventually make its way to the Swift Core Team, or Swift's bug reporter. Either of these may find your bug too broad or already known, however. The Swift team may also consider what you are looking for to be a new language feature, in which case you should first check out the mailing lists.

Update

In December 2016, this issue was reported to the Swift community. The issue is still marked as open with a medium priority, but the following comment was added:

This is intended. There is no way to add the implementation of the method to every adopter, since the extension could be added after the conformance to the protocol. I suppose we could allow it if the extension is in the same module as the protocol, though.

Since your protocol is in the same module as your extension, however, you may be able to do this in a future version of Swift.

Update 2

In February 2017, this issue was officially closed as "Won't Do" by one of the Swift Core Team members with the following message:

This is intentional: protocol extensions cannot introduce @objc entry points due to limitations of the Objective-C runtime. If you want to add @objc entry points to NSObject, extend NSObject.

Extending NSObject or even UIViewController will not accomplish exactly what you want, but it unfortunately does not look like it will become possible.

In the (very) long-term future, we may be able to eliminate reliance on @objc methods entirely, but that time will likely not come anytime soon since Cocoa frameworks are not currently written in Swift (and cannot be until it has a stable ABI).

Update 3

As of Fall 2019, this is becoming less of a problem because more and more Apple frameworks are being written in Swift. For example, if you use SwiftUI instead of UIKit, you sidestep the problem entirely because @objc would never be necessary when referring to a SwiftUI method.

Apple frameworks written in Swift include:

  • SwiftUI
  • RealityKit
  • Combine
  • CryptoKit

One would expect this pattern to continue over time now that Swift is officially ABI and module stable as of Swift 5.0 and 5.1, respectively.

참고URL : https://stackoverflow.com/questions/39487168/non-objc-method-does-not-satisfy-optional-requirement-of-objc-protocol

반응형