0

I can't for the life of me figure out how to store anything to do with an optional in NSCache. I can understand directly storing an optional would not make sense, but storing an array or dictionary where some options may be optional certainly seems like it should be possible.

Yet a simple example doesn't work:

let dict: [String: String?] = ["foo": "bar"]
NSCache().setObject(dict, forKey: "dict")

Is there something I'm overlooking or is there really no way to do this?

Doug Smith
  • 29,668
  • 57
  • 204
  • 388
  • I can understand how it wouldn't be able to try and store it if nothing really existed it wouldn't be able to set anything. Maybe you can iterate through that dict and create a new non optional one that you can use with NSCache. – Fred Faust Dec 22 '15 at 18:51
  • @thefredelement But in Objective-C it would work, as optionals essentially exist they're just unlabeled (i.e.: the same data structure in Objective-C would work). – Doug Smith Dec 22 '15 at 18:52
  • Yeah but I think there it's up to you when you try to access it to see if it's null or not, here it looks like you have to do that first. – Fred Faust Dec 22 '15 at 18:53
  • I'm not sure I understand what your suggestion is to do. What would the nil values have? Pretend it's an array where I can't simply remove indices because the value is nil as it would mess up index positioning. – Doug Smith Dec 22 '15 at 18:55
  • I'm not sure if I'm understanding but it sounds like you may need a second data structure to keep track of keys that may contain a nil value and some logic to see if those objects exists within your NSCache object. That would let you keep an index as well. – Fred Faust Dec 22 '15 at 19:00
  • it is a little weird though, I just tried with a custom object with nil properties and it works fine... – Fred Faust Dec 22 '15 at 19:05
  • @thefredelement everything is OK, Dictionary doesn't conform to AnyObject protocol. If your object conforms to it (like all Swift classes) you can save it in NSCache – user3441734 Dec 22 '15 at 19:22
  • @user3441734 that makes a lot of sense, I think NSCache can't work with value types. – Fred Faust Dec 22 '15 at 19:37
  • 1
    @thefredelement Still, swift dictionary should be bridged to `NSDictionary`. – Sulthan Dec 22 '15 at 19:41
  • @Sulthan you are right! (if the question is about dictionary - nsdictionary) generally, Optional is a struct, so it doesn't conform to AnyObject. if your value can be nil, you have to use implicitly unwrapped optional. – user3441734 Dec 22 '15 at 19:48

1 Answers1

1

the answer is

let dict: [String: String?] = ["foo": "bar"]
NSCache().setObject(dict, forKey: "dict")

error: argument type '[String : String?]' does not conform to expected type 'AnyObject' NSCache().setObject(dict, forKey: "dict")

protocol AnyObject { ... } The protocol to which all classes implicitly conform. Dictionary is a struct

class C {}
let cls: C = C()
NSCache().setObject(cls, forKey: "cls")

but!! if your cls can be nil, than you have to use implicitly unwrap optional.

let cls: C? = C()
NSCache().setObject(cls, forKey: "cls")
//error: value of optional type 'C?' not unwrapped; did you mean to use '!' or '?'?
NSCache().setObject(cls, forKey: "cls")

so you have to use

let cls: C! = C()
NSCache().setObject(cls, forKey: "cls")

Optional<Type> is a struct too!

user3441734
  • 16,722
  • 2
  • 40
  • 59