Pergunta

I have a database object and some photos objects.

The database object contains an integer property and a mutable dictionary property.

The integer keeps track of the next free number to use as a mutable dictionary key when I create a new photo object and the mutable dictionary contains pointers to photo objects.

Photo objects contain an image, an image description and the date the image was taken.

I've been using NSKeyedUnarchiver and NSKeyedArchiver to read and write these objects in and out when my applicationDidBecomeActive and applicationWillResignActive methods trigger.

And, it's all been working well. When applicationWillResignActive triggers, it calls NSKeyedArchiver and points it to the database object as the root. The coder then writes out the integer and then when it encounters the mutable dictionary, it descends into it and each photo object is called to save its properties which are the image, the description and the date.

As I said, it's all been working well. But, it has seemed slower and slower as the number of photos has increased so I did some timings.

I found that reading the archive in is roughly 25 times faster than writing it out.

So, I conceived the idea of only writing out the photos which are new or changed as a method of speeding up the write side. After all, most of the photos are from past sessions and I might have 30 or 50 of them from before and I might only shoot two or three new ones this time.

I created some flags that indicate if a photo is new or old. When applicationWillResignActive triggers and I find myself down in the photos object handling each encodeWithCoder call, I save the image, description and date if the photo is new and I skip saving if it is old.

Well, I did not get the result I'd hoped for :-)

When applicationWillResignActive triggers, all the photos I skip writing out end up getting written out as empty photo objects which overwrites the previous photo objects out there with the same key. Then, when I load them back in, I've got bupkis, nada, zip.

First question, I guess, is can I write out only part of my object tree and have the parts I don't write out still remain out there intact from an earlier full write? I'm beginning to wonder if that might be a naive idea.

Gallymon

Foi útil?

Solução

Using archives of some array of objects is going to be increasingly inefficient as the archive grows. This is exacerbated by the fact that your objects include images. Two thoughts:

  1. You should consider using Core Data for storing this data. (You could use SQLite, directly, too, but Core Data is the preferred object persistence technology in iOS.) This way, when you want to save a new object, you just add that new object, and don't archive the whole collection of objects every time.

  2. Furthermore, if speed is of primary interest and if your images are large, SQLite (the database that Core Data employs by default) is inefficient when handling large BLOBs (i.e. things like images). So, as inelegant as it sounds, you probably want to save images to your Documents folder, and only store a image file URL or path in CoreData.

Outras dicas

why don't you save the image only on the init method ? if you create the object chances are you want to save it. so place the flag hasChanges == off in the init method and you check that flag for saving...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top