TL; DR - >滚动到底部
在尝试使用Swift在面向协议的编程上标记Apple时,我在尝试在类之间实现委派模式时偶然发现了以下问题。
我将从这个例子开始:
protocol PhotoHandlerParent {}
class UIViewController {}
class MyViewController: UIViewController, PhotoHandlerParent {}
class PhotoHandler: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
weak var delegate: PhotoHandlerParent
}
到目前为止,这么好。 MyViewController
的实例将被愉快地指定为PhotoHandler
的委托。但是我说我不仅希望委托对象符合PhotoHandlerParent
,而且还要成为UIViewController
类。在此特定示例中,PhotoHandler
可以代表其父视图控制器显示和关闭UIImagePickerController
。很像:
protocol PhotoHandlerParent {}
class UIViewController {}
class MyViewController: UIViewController, PhotoHandlerParent {}
class PhotoHandler: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
weak var delegate: UIViewController, PhotoHandlerParent
}
不幸的是,上面的代码对Swift不起作用。另一方面,Swift确实有泛型,在这种情况下可能有所帮助。因此,有人可能会尝试:
protocol PhotoHandlerParent {}
class UIViewController {}
class MyViewController: UIViewController, PhotoHandlerParent {}
class PhotoHandler<Parent where Parent: UIViewController, Parent: PhotoHandlerParent>: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
weak var delegate: Parent
}
现在有趣的是,MyViewController
的一个实例会很高兴地被分配为PhotoHandler
的委托。没有编译错误,没有运行时错误。但...
TL; DR:问题
为这个问题运行sample code,可以看到用Generics声明并设置为UIImagePickerController
委托的类的实例永远不会被它调用。声明没有泛型的对象的实例由UIImagePickerController
调用。
我最好的假设是编译器不会抱怨,因为它可以验证PhotoHandler
是否符合UIImagePickerControllerDelegate
。但是,在运行时,PhotoHandler
实例实际上是一个PhotoHandler<MyViewController>
实例,因此会以某种方式干扰UIImagePickerController
识别其委托实际实现其协议的能力。
或者我错过了什么?
干杯
答案 0 :(得分:2)
从文档的角度来看,这是正确的行为,因为:
泛型类中的方法无法在Objective-C
中表示
回复@Bell App Lab 评论:
打开this page并向下滚动到 Lightweight Generics 。请注意:
除了这些Foundation集合类之外,还有Objective-C Swift忽略了轻量级泛型。任何其他类型使用 轻量级泛型被导入Swift,就好像它们一样 unparameterized。
它基本上表示泛型(ObjC - &gt; Swift)仅为Foundation集合类导入,而rest被忽略 - IOW导入,好像它们是未参数化的。
也许我们可以期待未来在这方面有所改善,但我对此表示怀疑。