0

I have an NSMutableDictionary which contains UIImageView objects and UIView keys.

When I am setting an UIImageView to the NSMutableDictionary I get the NSValue out from the UIView like this:

[viewImageMap setObject:anImage forKey:[NSValue valueWithNonretainedObject:aView]];

I want to know if there is anyway I can obtain the UIView reference back with the NSValue object. Something like this:

UIView *aView = (UIView *)[NSObject objectWithValue:aValue];
jscs
  • 63,694
  • 13
  • 151
  • 195
JLT
  • 3,052
  • 9
  • 39
  • 86
  • 1
    If the reason for packing the reference into an instance of `NSValue` is copying and strength, you can take into account the usage of `NSMapTable`(https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSMapTable_class/index.html#//apple_ref/occ/cl/NSMapTable), too. It is a more configurable dictionary, esp. it allows to assign a weak reference. – Amin Negm-Awad Jun 02 '16 at 15:24
  • @AminNegm-Awad Thank you. I'll try that. – JLT Jun 02 '16 at 15:43

2 Answers2

2

Here is how to do so:

NSValue * myViewKey = [NSValue valueWithNonretainedObject:myView];
UIView * myViewFromValue = (UIView*) myViewKey.nonretainedObjectValue
Julien Quere
  • 2,407
  • 16
  • 21
  • That's why the OP is using an `NSValue`, which does conform to `NSCopying`. – jscs May 12 '16 at 06:57
  • Sure, but I still think that's not a good idea in terms of architecture. – Julien Quere May 12 '16 at 07:04
  • Thanks! but can you give me just one reason why it isn't a good idea? – JLT May 12 '16 at 07:06
  • I just edited my answer with an explanation on that. – Julien Quere May 12 '16 at 07:15
  • It's _not_ retained by the `NSValue`; that's what **`Nonretained`** means. – jscs May 12 '16 at 07:48
  • No, but `NSDictionary` did. Take the code above, execute it, and look at the `myView` retainCount. – Julien Quere May 12 '16 at 09:20
  • @JulienQuere Thanks. I'll verify this. – JLT May 12 '16 at 10:19
  • That's not an `NSDictionary` retaining the view. that's ARC, and it's because you've created two new strong references to the view when you unpack the value. The dictionary would only have a strong reference to the enclosing `NSValue`. @JLT – jscs May 12 '16 at 17:43
  • @JoshCaswell hmm, I am a bit confused. Why are there two new strong references when I unpack the value? I thought there's only one, which is the reference that I assigned to the unpacked value. -> UIView * theView = [theValue nonRetainedObjectValue]; – JLT May 13 '16 at 01:44
  • There are two references in _Julien's_ code, @JLT: `myViewFromValue` and `mySecondViewFromValue`. The line you just wrote in that comment has only one, yes. – jscs May 13 '16 at 04:40
  • @JoshCaswell Ah I see, so you are referring to his code. Alright, I get it now. Thanks! – JLT May 13 '16 at 05:54
  • Hum, my bad, I was completely mistaken. I edit my answer. I'm truly sorry. – Julien Quere May 13 '16 at 06:44
2

For each valueWith<Type>: method, NSValue has a complementary method that returns the stored value in the appropriate type.

The one you need is nonRetainedObjectValue.

UIView * theView = [theValue nonRetainedObjectValue];
jscs
  • 63,694
  • 13
  • 151
  • 195