1

I need a dictionary to hold a limited number of objects that need to be created with an internet connection and cache them so they remain available when there's no internet connection.

NSCache seems ideal since I can specify a limit or it will automatically adjust itself based on available memory, but I can't save the object to NSUserDefaults. If I try caching like this, which worked for NSDictionary:

+ (void)cacheUsers:(NSCache *)users {
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:users];
    [[NSUserDefaults standardUserDefaults] setObject:data forKey:kCacheID];
}

the app crashes: [NSCache encodeWithCoder:]: unrecognized selector sent to instance

Should I convert the NSCache to an NSDictionary before caching and then convert again when retrieving? Or is there a better way to save an NSCache?

Cbas
  • 6,003
  • 11
  • 56
  • 87
  • NSCache doesn't implement NSCoding, so you cannot archive it. – Tamás Zahola Feb 17 '16 at 20:00
  • 1
    Also, I wonder how do you plan converting the cache into a dictionary? NSCache has no API for iterating through the contents... – Tamás Zahola Feb 17 '16 at 20:02
  • yea that would be my next question. I guess I have to extend NSMutableDictionary to make it basically the same as an NSCache... ok apple – Cbas Feb 17 '16 at 20:03
  • What are you trying to achieve exactly? – Tamás Zahola Feb 17 '16 at 20:05
  • I want to load user objects from the web and cache them so they're always available. But there could be an infinite number of objects, so I need to release memory at some point – Cbas Feb 17 '16 at 20:06
  • 1
    I see. In this case you indeed need to write your own object repository that discards items in a well-defined manner and supports archiving. IMO NSCache wouldn't be suited for this (even if you could archive it), because Apple makes no guarantees regarding its eviction policy. E.g. on iOS all NSCaches are cleared when the app goes to the background. – Tamás Zahola Feb 17 '16 at 20:10
  • ok thanks that answers it – Cbas Feb 17 '16 at 20:13

1 Answers1

0

I assume that you are trying to save an array with custom class objects, For that You need to implement the methods named 'encodeWithCoder' in your custom class, in order to save it to NSUserDefault.

To me, You don't need to using the NSCache.

See related answer below: https://stackoverflow.com/a/2315972/1982185

Good luck!

Community
  • 1
  • 1
Kun Wang
  • 81
  • 1
  • 6
  • Why not just save an array with custom objects, instead of array with NSCache. – Kun Wang Feb 17 '16 at 20:00
  • There could be an infinite number of users loaded, so I need to be able to release some when memory is tight. – Cbas Feb 17 '16 at 20:00
  • Also, an NSCache is not an array, its a dictionary – Cbas Feb 17 '16 at 20:01
  • I mean save an array with custom objects to NSUserDefault. – Kun Wang Feb 17 '16 at 20:05
  • Oh there was a typo in my code that made it look like an array. Sorry for the confusion. I've updated – Cbas Feb 17 '16 at 20:07
  • I think you don't want actually to save an NSCache, what you want to save is the object(image or user info) which is cached by NSCache, if this is correct, why not just forget the NSCache, and save the object to NSUserDefault. – Kun Wang Feb 17 '16 at 20:11
  • I see what you mean - NSUserDefault is a also dictionary - but I need an object to manage the memory – Cbas Feb 17 '16 at 20:15
  • how about follow library:https://github.com/pinterest/PINCache https://github.com/tumblr/TMCache https://github.com/Haneke/HanekeSwift – Kun Wang Feb 17 '16 at 22:15