我尝试使用添加的属性创建UIImage的子类,但是当我创建一个便利init时,我无法调用UIImage的指定init init(命名名称:String)因为某些原因它不是遗传的。
class myUIImage: UIImage {
var imageType$: String?
convenience init(imageName$ imageName$: String) {
self.init(...?)
self.imageType$ = // ...
}
}
有什么想法吗?
答案 0 :(得分:6)
UIImage
并非设计为子类(您在其文档中注意缺少"子类注释")。正如您所发现的那样,尝试将其子类化有许多棘手的小问题。这在与Core Foundation类密切相关的Cocoa类中非常常见(在本例中为UIImage
和CGImageRef
)。
通常你应该用组合而不是继承来解决这个问题。创建一个包含image
和imageType
属性的新结构,然后使用它。
如果有更深层次的原因需要将类型附加到真实的UIImage
,可以使用运行时技巧(参见objc_setAssociatedObject
)来完成,但这应该保留给组合的情况不可能。最常见的是当您将对象传递给某个API时,该API稍后会将其传回给您,并且您需要传递一些旁道信息。我在处理UIAlertView
时经常使用它,但通常简单的组合更好。
答案 1 :(得分:2)
有"没有继承" named中的字符串:初始化程序声明:
public /*not inherited*/ init?(named name: String) // load from main bundle
我不确定"没有继承"完全代表,但看起来它真正的本质是"便利初始化"并且你不能在子类中使用它。至少它表现得像这样。 所以,我建议你采取以下方式:
class TheImage: UIImage {
var param: String! = nil
convenience init?(param: String) {
guard let image = UIImage(named: "TheImage") where nil != image.cgImage else {
return nil
}
self.init(cgImage: image.cgImage!)
self.param = param
}
}
另一方面,通常你不需要继承UIImage。在大多数情况下,创建一个包装类就足够了,而且更合适。
答案 2 :(得分:0)
子类化UIImage有点时髦。但它可以做到
class PlaceHolderIcon: UIImage {
// any additional properties can go here
override init() {
let image = UIImage(named: "image-name")!
super.init(cgImage: image.cgImage!, scale: UIScreen.main.scale, orientation: .up)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
required convenience init(imageLiteralResourceName name: String) {
fatalError("init(imageLiteralResourceName:) has not been implemented")
}
}