我有一个UIButton的自定义子类:
import UIKit @IBDesignable class MyButton: UIButton { var array : [String]? }
它是IBDesignable,并且已将其设置为情节提要中按钮之一的自定义类。我想使其通用,以便该数组不必是String对象之一。所以,我尝试了这个:
import UIKit @IBDesignable class MyButton<T>: UIButton { var array : [T]? }
但是,我不确定现在如何在IB中将其设置为类。我尝试放置MyButton<String>或MyButton<Int>,但是Interface Builder只是删除了尖括号部分并得到以下编译错误:
MyButton<String>
MyButton<Int>
Command /Applications/Xcode6-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254
有没有使用通用自定义类的方法,或者不支持该类?
Interface Builder通过ObjC运行时与代码“对话”。这样,IB只能访问在ObjC运行时中可表示的代码功能。ObjC不执行泛型,因此IB无法告诉运行时要使用泛型类的哪个专业化。(而且Swift泛型类不能在没有专门化的情况下实例化,因此尝试实例化a MyButton而不是实例化时会出现错误MyButton<WhateverConcreteType>。)
MyButton
MyButton<WhateverConcreteType>
(当您破坏其他情况时,您可以识别IB中的ObjC运行时:尝试在nib / storyboard中使用带有出口/动作的纯Swift类会产生有关ObjC自省的运行时错误。将出口连接起来,其对应的代码声明已更改或消失会导致有关KVC的运行时错误。等等。)
要忽略运行时问题,并以稍微不同的方式进行处理…让我们回到IB需要了解的内容。请记住,笔尖加载系统是在运行时实例化情节提要中任何内容的系统。因此,即使您的类中带有泛型类型参数的部分不是@IBInspectable,笔尖仍然需要知道要加载的泛型类的什么特殊化。因此,为了使IB允许您将通用类用于视图,IB必须有一个位置供您标识笔尖应使用哪种专业。不需要- 但这会带来很棒的功能要求。
@IBInspectable
同时,如果让您的MyButton班级涉及一些通用存储仍然很有帮助,也许您可以考虑MyButton参考另一个包含通用存储的类。(尽管这样做的方式必须确保在编译时不知道所述存储的类型,否则其他类的类型参数必须传播回MyButton。)