Swift泛型和协议不适用于UIKit [可能的错误]

时间:2015-07-02 14:37:34

标签: swift generics delegates protocols

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识别其委托实际实现其协议的能力。

或者我错过了什么?

干杯

1 个答案:

答案 0 :(得分:2)

从文档的角度来看,这是正确的行为,因为:

  

泛型类中的方法无法在Objective-C

中表示

回复@Bell App Lab 评论:

打开this page并向下滚动到 Lightweight Generics 。请注意:

  

除了这些Foundation集合类之外,还有Objective-C   Swift忽略了轻量级泛型。任何其他类型使用   轻量级泛型被导入Swift,就好像它们一样   unparameterized。

它基本上表示泛型(ObjC - &gt; Swift)仅为Foundation集合类导入,而rest被忽略 - IOW导入,好像它们是未参数化的。

也许我们可以期待未来在这方面有所改善,但我对此表示怀疑。