Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

non reference-counting dictionary in objective-c

Tags:

objective-c

Is there any 'easy' way of having pure objective-c containers, such as NSMutableDictionary or CFMutableDictionary, that don't increment the reference count of added objects, without using the c++ standard library?

EDIT: Explanation - the reason I want this is so I can implement a kind of "Exactly One" pattern - a class will have a static getThing:(NSString*)name method. If that method finds a Thing associated with the name in some static datastructure (the non reference-counting dictionary), it returns it, otherwise it creates one, adds it to the structure under that name, and returns it. That Thing object can be retained by the client at will, but when its reference count falls to 0 (and dealloc is called), it should be removed from the dictionary. Thus, I can't release it when adding and retain it again when removing it - dealloc would get called again, and I don't want that. That's why I need the non incrementing dictionary. If there's another way to get what I want, please let me know, although I'm pretty sure that the checked answer gives me what I want. Thanks!

like image 539
Colin Avatar asked Jun 15 '10 03:06

Colin


3 Answers

If you are developing for MacOSX, then you can use NSMapTable. See this blog post from Mike Ash to learn more about it.

If you are developing for iPhone, then you can use CFMutableDictionary with a custom callback structures:

  • copy the kCFTypeDictionaryKeyCallBacks and kCFTypeDictionaryValueCallBacks structures into new ones.
  • put the retain and release fields to NULL where you don't need to retain/release (key and/or values).
  • pass the structures when calling CFDictionaryCreateMutable.

This way, you will have a dictionary that does neither retain nor release.

like image 155
Laurent Etiemble Avatar answered Nov 05 '22 07:11

Laurent Etiemble


Why would you need a non-reference counting container? If you are storing ordinary values (like integers), you can wrap them in type NSValue and if you have some other type, but you don't want that many reference counts, simply invoke "release" on it immediately after you add it to the container.

like image 23
Michael Aaron Safyan Avatar answered Nov 05 '22 09:11

Michael Aaron Safyan


You could create an NSValue representing each object with the valueWithPointer: method. Adding the values to the collection instead would not retain the referenced object. This is pretty gross, so consider if there might not be a better way to achieve your aim than sidestepping container ownership of contained objects.

like image 1
warrenm Avatar answered Nov 05 '22 08:11

warrenm