views:

286

answers:

2

Hello,

I'm currently populating model objects into an NSSet (perhaps I should be using NSCountedSet). The models should be unique. What I do is pull them in from a web service, and then instantiate them on the client-side and add them to a set.

My problem is the following: There are times when I'll only pull one model and add it to the set, for instance say I have an inventory of Ferrari's. So I'll ask my server to pull me in one specific Ferrari because an individual clicks on that Ferrari's detail view from an inventory. The individual Ferrari detail view will list all of the different paints available for this model. So once the user drills into this Ferrari view, I will ask the server for all of the paints available for a particular Ferrari model.

Next, the user backs out and then goes to a view controller which asks for all of the paint colors I have available for every vehicle. I already have the Ferrari paints available in a stash. Now I'm asking for ALL of the paints from the server. What's the best way to aggregate the existing paints with all of the paints without duplicating resources?

+2  A: 

What you need is a way to uniquely identify each object from the server. In a database an object (part or whole) can be represented as a row and the rowid is typically a monotonically increasing integer (although your data source could use something else). In any case, store this unique id in each object you create, and before creating a new object check for the existence of an object with that id. If the object already exists, return the existing object, and if it doesn't, create a new object and then store it in the cache. Using integers as ids works out nicely, because you can use NSMapTable as a cache with the rowids as the keys, and the values are the object pointers.

sbooth
A: 

Maintain an NSArray* in your app which stores NSString* objects based on some hash function of your features:

hashValue = hash(color + horsepower + leatherSeating + whatever...)

For example, you might take the SHA1 hash of a collated string (example code).

Take the features you obtain from the web service and generate a hashed value from them using the same function.

Search your app's hash table for the web-service-value using -containsObject:.

If it returns YES, do X, else do Y.

Alex Reynolds
Why not just implement -hash in the model object class and continue using NSSet?
Peter Hosey
If you cache the hash values in an array, you won't have to recalculate them each time you do a comparison.
Alex Reynolds
And what's to stop you caching the result of -hash as part of the class's -hash implementation?
Mike Abdullah