使用添加的属性创建UIImage的子类

时间:2016-01-15 18:33:39

标签: swift inheritance uiimage initializer

我尝试使用添加的属性创建UIImage的子类,但是当我创建一个便利init时,我无法调用UIImage的指定init init(命名名称:String)因为某些原因它不是遗传的。

class myUIImage: UIImage {
    var imageType$: String?
    convenience init(imageName$ imageName$: String) {
        self.init(...?)
        self.imageType$ = // ...
    }
}

有什么想法吗?

3 个答案:

答案 0 :(得分:6)

UIImage并非设计为子类(您在其文档中注意缺少"子类注释")。正如您所发现的那样,尝试将其子类化有许多棘手的小问题。这在与Core Foundation类密切相关的Cocoa类中非常常见(在本例中为UIImageCGImageRef)。

通常你应该用组合而不是继承来解决这个问题。创建一个包含imageimageType属性的新结构,然后使用它。

如果有更深层次的原因需要将类型附加到真实的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")
    }

}