34

I have set of data which contains images also. I want to cache this data. Should i store them on file system or on core data and why?

Regexident
  • 29,441
  • 10
  • 93
  • 100
Abhinav
  • 37,684
  • 43
  • 191
  • 309

3 Answers3

40

There are two main options:

  1. Store the file on disk, and then store the path to the image in core data
  2. Store the binary data of the image in core data

I personally prefer the 1st option, since it allows me to choose when I want to load the actual image in memory. It also means that I don't have to remember what format the raw data is in; I can just use the path to alloc/init a new UIImage object.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • So do you mean to say if I am storing the image as binary data in Core data, I need to know the original file format while restoring it. Is there any other disadvantage of storing data in Core Data? – Abhinav Nov 11 '10 at 20:48
  • 1
    @Abhinav correct; the other thing i'd say is that by keeping the image out of Core Data, you're keeping your store file small. Whether that's a disadvantage would be answered by lots and lots of performance profiling. :) – Dave DeLong Nov 11 '10 at 21:13
  • So this means keeping heavier image files out side the Core Data would increase the app performance. Did I understood it correctly? – Abhinav Nov 11 '10 at 22:00
  • 1
    @Abhinav I think it might; you'd want to confirm that suspicion through profiling with Instruments, etc. – Dave DeLong Nov 11 '10 at 22:01
  • 4
    Marcus Zarra recommends saving small images directly in your Core Data store, saving large ones to disk & at an intermediate size saving them to a dedicated table. He goes on to suggest using up to 2 of those techniques to cover a spread of image sizes. See http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/ – Pedro Oct 09 '11 at 00:10
  • @DaveDeLong but if you create a separate entity for the core data image and set a relationship in core data to another entity you shouldn't need to load everything into memory at once. you can say UIImage *img = managedObj.image and it will do the fetch then. – Remover Feb 26 '12 at 13:29
  • 1
    The larger your Core Data becomes, the more likely you are to run into problems doing core data migrations. And even small images in core data will bloat it up if you have enough of them. For that reason, I prefer to keep images on disk. Those aren't insurmountable problems, but they are extra hassle. – occulus Jan 31 '13 at 13:01
  • It is not true that you have to remember what format the data is in when storing it in CoreData. [UIImage imageWithData:] doesn't require you to tell it the format. – honus Jun 19 '13 at 21:03
16

You might want to read this from the Core Data Programming Guide on how to deal with binary large objects (BLOBs). There are rules of thumb for what size binary data should and should not be stored within the actual Core Data store.

You might also look at Core Data iPad/iPhone BLOBS vs File system for 20k PDFs

If you do place binary data within Core Data store, you would do well to have a "Data" entity that holds the actual data and to have your "Image" entity separate. Create a relationship between the two entities, so that "Data" need only be loaded when actually needed. The "Image" entity can hold the meta-data such as title, data type, etc.

Tony Edgecombe
  • 3,860
  • 3
  • 28
  • 34
westsider
  • 4,967
  • 5
  • 36
  • 51
0

With regards to where to store the user data/files (I found "application support" to be a decent location given that i was wary of the user moving, deleting or altering the file in some way that would result in the image not being able to be recovered and used later by my application)

Take minecraft as an example: eg. "~/Library/Application Support/minecraft/saves/"

I would agree with the previous comments and store paths to the images in core data but otherwise store the images themselves as png files in their own folder outside of core data.

eric bob
  • 235
  • 2
  • 11