Non-'@objc' method 'presentationController(_:viewControllerForAdaptivePresentationStyle:)' does not satisfy optional requirement of '@objc' protocol 'UIAdaptivePresentationControllerDelegate'
@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
功能可能当前不在协议扩展中。您可以创建一个基类,尽管这不是理想的解决方案。
首先,这个问题/答案(可以在Objective-c中访问的协议扩展上定义了Swift方法似乎表明,由于协议扩展是在后台分发的,因此objc_msgSend()
函数中不可见协议扩展中声明的方法,并且因此对Objective-
C代码不可见。由于您尝试在扩展中定义的方法需要对Objective-
C可见(因此UIKit
可以使用),因此对您大喊不包含@objc
,但一旦包含了它,您就会对您大喊,因为@objc
不允许协议扩展。这可能是因为协议扩展当前对Objective-
C不可见。
我们还可以看到,一旦添加了@objc
状态“ @objc只能与类的成员,@ objc协议和类的具体扩展一起使用”
,该错误消息就会出现。这不是一堂课。@objc协议的扩展名与协议定义本身(即在要求中)不同,并且单词“
concrete”将表明协议扩展名不算作具体的类扩展名。
不幸的是,当默认实现必须对Objective-
C框架可见时,这几乎完全阻止您使用协议扩展。刚开始,我认为@objc
您的协议扩展中可能不允许这样做,因为Swift编译器无法保证符合类型的是类(即使您已明确指定UIViewController
)。因此,我对提出了class
要求P1
。这没有用。
也许唯一的解决方法是在这里简单地使用基类而不是协议,但这显然不是完全理想的,因为一个类可能只有一个基类,但符合多种协议。
如果您选择走这条路线,请考虑以下问题(在子类中未调用Swift 3
ObjC可选协议方法。看来,Swift3中的另一个当前问题是子类不会自动继承其超类的可选协议要求实现。这些问题的答案使用特殊的改编@objc
来解决。
我认为这已经在Swift开源项目的那些工作人员中进行了讨论,但是您可以确定使用Apple的Bug
Reporter(可能最终会进入Swift核心团队)或Swift的Bug记者了解他们的情况。但是,这两种方法都可能会发现您的错误范围太广或已知。Swift团队可能还会将您正在寻找的内容视为一项新的语言功能,在这种情况下,您应该先查看邮件列表。
2016年12月,此问题已报告给Swift社区。该问题仍被标记为具有中等优先级的未解决问题,但是添加了以下注释:
这是有意的。无法将方法的实现添加到每个采用者,因为扩展可以在符合协议之后添加。我想如果扩展名与协议在同一个模块中,我们可以允许它。
由于您的协议与扩展名在同一个模块中,因此您可以在以后的Swift版本中执行此操作。
2017年2月,Swift核心团队的一名成员正式以“ Wo n’t
Do”的形式关闭了此问题,并显示以下消息:
这是故意的:由于Objective-
C运行时的限制,协议扩展无法引入@objc入口点。如果要将@objc入口点添加到NSObject,请扩展NSObject。
扩展NSObject
甚至UIViewController
无法完全实现您想要的功能,但是不幸的是,它看起来不可能实现。
在(非常长远的)未来中,我们也许可以@objc
完全消除对方法的依赖,但是由于Cocoa框架当前不是用Swift编写的(并且直到它具有稳定的ABI才可以),这种情况可能不会很快出现。
。
截至2019年秋季,这已经成为一个问题,因为越来越多的Apple框架正在用Swift编写。例如,如果您使用SwiftUI
而不是UIKit
,那么您将完全避开该问题,因为@objc
在引用SwiftUI
方法时将永远不需要。
用Swift编写的Apple框架包括:
现在,随着Swift正式成为ABI和模块稳定版本(分别自Swift 5.0和5.1开始),人们可能会希望这种模式随着时间的推移而继续下去。
问题内容: 我有以下类层次结构: 实现一种协议方法,例如 在继承自的类中,不再调用新的可选协议方法,例如 问题答案: tl; dr,您需要在函数声明之前添加其Objective-C声明,例如 借助《Swift 3迁移指南》,我被告知这是一个解决方案,其中指出: 如果在声明符合性的类的子类中实现可选的Objective-C协议要求,则会看到警告,“实例方法’…’几乎与协议’…’的可选要求’…’相匹配
问题内容: 好的,这是个大问题。我有一个用ObjC(this)编写的库。在那里,我们有一个已定义的协议。当我尝试在快速文件中使用它时,我经常得到: 类型“ XXX”不符合协议“ XXX” 为简化起见,我组成了一个测试项目-应该将其创建为Swift项目。 然后使用以下协议在内部创建ObjC头文件(我称其为StupidProtocol.h)(请注意,每个名称和值都应与给定的值完全匹配,包括大写/小写)
graphael-objc 是对 gRaphael 图形图表库的 Objective-C 语言封装。
cocos2d-spritebuilder 是用于 iOS 及 OS X 的 2D 游戏框架。
DXCustomCallout-ObjC 是一个在 MKMapview 上实现 CustomCallouts 的简单方法。
SpinKit-ObjC 是 iOS 加载组件,带有平滑酷炫的动态效果。