Is there a way to store a selector in an NSDictionary
, without storing it as an NSString
?
5 Answers
SEL
is just a pointer, which you could store in an NSValue
:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSValue valueWithPointer:@selector(foo)], @"foo",
nil];
To get the selector back, you can use:
SEL aSel = [[dict objectForKey:@"foo"] pointerValue];

- 97,545
- 26
- 194
- 236
-
6Maybe also mention that to get the SEL back, you have to do: `SEL *aSel = [[dict objectForKey:@"foo"] pointerValue];` – dreamlax May 12 '10 at 20:54
-
1When I retrieve SEL as you suggest and try self performSelector:*aSel withObject:nil afterDelay:0.0]; I get: EXC_BAD_ACCESS. The correct way of retrieving them is SEL aSel = [[dict objectForKey:@"foo"] pointerValue]; [self performSelector:aSel withObject:nil afterDelay:0.0]; – nacho4d Aug 24 '10 at 03:29
-
Newbie question: How do you execute your selector? – Johan Karlsson May 13 '13 at 13:34
-
@JohanKarlsson: E.g. using one of the `performSelector:` variants. More detail would be better suited for a new question though. – Georg Fritzsche May 13 '13 at 14:01
-
1@GeorgFritzsche IMHO your answer would be more complete if you just add one row as an example on how to use the SEL. Not so much work, but nice. Only a suggestion. I agree that how to use selector in a more wide approach could be a question own its own. – Johan Karlsson May 22 '13 at 06:17
-
Ah, this is why I'm still in love with Objective-C - it's super dynamic and total freedom for the mind! :) – turingtested May 03 '18 at 08:52
An alternative to Georg's solution would be to convert the selector into an NSString before storing it the NSDictionary:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
NSStringFromSelector(@selector(foo)), @"foo",
nil];
SEL selector = NSSelectorFromString([dict objectForKey:@"foo"]);
This technique, though uses more memory, gives you the ability to serialize the entire NSDictionary as a string via libraries like JSONKit.

- 2,901
- 1
- 26
- 21
-
Georg, it was my fault. I did set a selector for the dictionary key used to retrieve it. Thanks for following up. I'll update my answer. – David H Feb 16 '12 at 02:02
-
*Oops, typo. I meant to say: "I forgot to set a selector value for that key in the dictionary." – David H Feb 16 '12 at 02:14
-
1
-
1If you're using strings for the selector names I would recommend using `[obj respondsToSelector:selector]` to guard against typos. – Oliver Mason Feb 21 '14 at 14:49
An NSDictionary
is really just a CFDictionary
that retains and releases all keys and values. If you create a CFDictionary
directly, you can set it up to not retain and release values. You can typecast a CFDictionaryRef
to an NSDictionary *
and vice versa.

- 53,459
- 16
- 107
- 112
-
I do this quite a bit for when I have Foundation objects as keys but non-Foundation objects as values. – dreamlax May 12 '10 at 20:52
While Georg's answer should work, NSValue
does also support encoding any value using an Objective-C type encoding string, which has a special way of representing SEL
— with a ":"
(as opposed to the "^v"
produced by -valueWithPointer:
, which translates into void *
).
source: Objective-C Runtime Programming Guide - Type Encodings
Working off of Georg's solution, the best API-compliant way to put a SEL
into an NSValue
into an NSDictionary
would be:
// store
NSDictionary *dict = @{
@"foo": [NSValue value:&@selector(foo) withObjCType:@encode(SEL)]
};
// retrieve
SEL aSel;
[dict[@"foo"] getValue:&aSel];
The rationale for handling a SEL
as its own beast is that the docs describe it as “an opaque type”— which means that its internal workings (even what it's typedef
d to) are off-limits to app programmers; Apple may mix it up at any time in the future.
Also, using void *
s to force the system to do what you want it to do was useful in C back in the '90s, when most of us didn't know any better. You're better than that now.
The above approach should only be used if the retrieval of the SEL
happens during the program's running duration— you shouldn't be storing that NSDictionary
to disk. If you do need to store SEL
s long-term (across app launches), you should follow David H's approach and convert it to an NSString
.

- 1
- 1

- 33,165
- 3
- 43
- 43