创建具有附加属性的 UIImage 子类



我正在尝试创建一个带有附加属性的 UIImage 子类,但是当我创建一个方便的 init 时,我无法调用 UIImage 指定的 init init(名为 name: String),因为由于某种原因它不是继承的。

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

有什么想法吗?

UIImage不是为子类而设计的(你会注意到它的文档中缺少"子类化注释")。正如您所发现的,尝试对其进行子类化有许多棘手的小问题。这在与核心基础类密切相关的可可类中很常见(在这种情况下是UIImageCGImageRef)。

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

如果有更深层次的原因需要将类型附加到真正的UIImage,这可以通过运行时技巧来完成(见objc_setAssociatedObject),但这应该保留在无法组合的情况下。最常见的是当您将对象传递给某个 API 时,该 API 稍后会将其交还给您,并且您需要随之传递一些侧信道信息。我在处理UIAlertView时经常使用它,但通常简单的构图更好。

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进行子类化。在大多数情况下,创建一个包装类就足够了,而且更合适。

Subclassing 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")
    }
}

最新更新