Create a subclass of UIImage with added properties

别来无恙 提交于 2019-12-12 06:26:10

问题


I'm trying to create a subclass of UIImage with an added property, but when I create a convenience init, I can't call the UIImage's designated init init(named name: String) because for some reason it's not inherited.

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

Any ideas?


回答1:


There is "not inherited" string in named: initializer declaration:

public /*not inherited*/ init?(named name: String) // load from main bundle

I am not sure what "not inherited" exactly stands for, but looks like its real nature is "convenience initializer" and you cannot use it in subclasses. At least it behaves like this. So, I'd propose you to go the following way:

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
    }
}

From other hand, usually you don't really need to subclass UIImage. In most of cases creating a wrapper class would be sufficient and much more appropriate.




回答2:


UIImage is not designed to be subclassed (you'll note a lack of "Subclassing notes" in its documentation). There are many tricky little problems with trying to subclass it, as you've discovered. This is pretty common in Cocoa classes that are closely associated with Core Foundation classes (UIImage and CGImageRef in this case).

Generally you should solve this with composition rather than inheritance. Create a new struct that includes image and imageType properties and just use that.

If there is some deeper reason that you need to attach the type to a real UIImage, that can be done with runtime tricks (see objc_setAssociatedObject), but this should be reserved for cases where composition is not possible. The most common is when you pass an object to some API that will later hand it back to you, and you need to pass some side-channel information along with it. I've often used this when dealing with UIAlertView, but generally simple composition is better.




回答3:


Subclassing UIImage is a bit funky. But it can be done

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

}


来源:https://stackoverflow.com/questions/34817542/create-a-subclass-of-uiimage-with-added-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!