使用添加的属性创建 UIImage 的子类
Create a subclass of UIImage with added properties
我正在尝试创建一个添加了 属性 的 UIImage 的子类,但是当我创建一个方便的初始化时,我无法调用 UIImage 的指定初始化 init(named name: String) 因为对于由于某些原因它没有被继承。
class myUIImage: UIImage {
var imageType$: String?
convenience init(imageName$ imageName$: String) {
self.init(...?)
self.imageType$ = // ...
}
}
有什么想法吗?
named:initializer 声明中有 "not inherited" 个字符串:
public /*not inherited*/ init?(named name: String) // load from main bundle
我不确定 "not inherited" 到底代表什么,但看起来它的真实性质是 "convenience initializer" 并且你不能在 subclasses 中使用它。至少它的行为是这样的。
所以,我建议你走下面的路:
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
}
}
从另一方面来说,通常你真的不需要子class UIImage。在大多数情况下,创建包装器 class 就足够了,而且更合适。
UIImage
不是为子类设计的(您会注意到其文档中缺少 "Subclassing notes")。正如您所发现的那样,尝试对其进行子类化有很多棘手的小问题。这在与 Core Foundation 类 密切相关的 Cocoa 类 中很常见(在本例中为 UIImage
和 CGImageRef
)。
通常你应该用组合而不是继承来解决这个问题。创建一个包含 image
和 imageType
属性的新结构,然后使用它。
如果有更深层次的原因需要将类型附加到真实的 UIImage
,这可以通过运行时技巧来完成(请参阅 objc_setAssociatedObject
),但这应该保留用于某些情况不可能合成的地方。最常见的是当您将一个对象传递给一些 API 稍后将它返回给您时,您需要将一些 side-channel 信息与其一起传递。我在处理 UIAlertView
时经常使用它,但通常简单的组合更好。
子类化 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")
}
}
我正在尝试创建一个添加了 属性 的 UIImage 的子类,但是当我创建一个方便的初始化时,我无法调用 UIImage 的指定初始化 init(named name: String) 因为对于由于某些原因它没有被继承。
class myUIImage: UIImage {
var imageType$: String?
convenience init(imageName$ imageName$: String) {
self.init(...?)
self.imageType$ = // ...
}
}
有什么想法吗?
named:initializer 声明中有 "not inherited" 个字符串:
public /*not inherited*/ init?(named name: String) // load from main bundle
我不确定 "not inherited" 到底代表什么,但看起来它的真实性质是 "convenience initializer" 并且你不能在 subclasses 中使用它。至少它的行为是这样的。 所以,我建议你走下面的路:
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
}
}
从另一方面来说,通常你真的不需要子class UIImage。在大多数情况下,创建包装器 class 就足够了,而且更合适。
UIImage
不是为子类设计的(您会注意到其文档中缺少 "Subclassing notes")。正如您所发现的那样,尝试对其进行子类化有很多棘手的小问题。这在与 Core Foundation 类 密切相关的 Cocoa 类 中很常见(在本例中为 UIImage
和 CGImageRef
)。
通常你应该用组合而不是继承来解决这个问题。创建一个包含 image
和 imageType
属性的新结构,然后使用它。
如果有更深层次的原因需要将类型附加到真实的 UIImage
,这可以通过运行时技巧来完成(请参阅 objc_setAssociatedObject
),但这应该保留用于某些情况不可能合成的地方。最常见的是当您将一个对象传递给一些 API 稍后将它返回给您时,您需要将一些 side-channel 信息与其一起传递。我在处理 UIAlertView
时经常使用它,但通常简单的组合更好。
子类化 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")
}
}