I have an image in Core Data. It has to be saved as NSData, and I have a computed property to get and set the image based on the Core Data property imageData
:
var image: UIImage? {
get {
if let imageData = imageData {
return UIImage(data: imageData)
} else {
return nil
}
}
set {
if let image = image {
imageData = UIImagePNGRepresentation(image)
} else {
imageData = nil
}
}
}
However, I believe that this code will convert between UIImage
and NSData
every time the image is fetched, which can be very often since this data is used to populate a UITableViewCell
. Is this true, or is Xcode smart enough to cache computed properties in some way? Also, is this the recommended way of fetching images from Core Data, or is it recommended to fetch it once and save it to a new property like this (unsure if this code is correct):
lazy var image: UIImage? = {
if let imageData = imageData {
return UIImage(data: imageData)
} else {
return nil
}
}()
The downside of the last one the way I see it is that it would be possible to change imageData
without image
being updated. I'm also not sure if I can just use didSet
in the latter version to update Core Data.
Assuming that imageData
is a property of the entity description,
imageData
.image
will not be cached, and will be recomputed every time.If you're going to store images in Core Data, the right approach is simpler than you're making it. UIImage
conforms to NSCoding
, which means you can just create an image
attribute with the Core Data "transformable" type. Core Data will then automatically invoke NSCoding
methods to convert to/from UIImage
and you don't need any of the code in your question. You just read/write your UIImage
.
If you're going to store images in Core Data, using any scheme, make sure that the images aren't too large. Core Data can handle them but you may find that the image data gets loaded when you don't expect. For example, if you're only using other non-image attributes of a managed object, but the image data gets loaded anyway.