"Initializer element is not constant" for NSNumbers

Member
Posts: 35
Joined: 2009.10
Post: #1
I'm using an NSMutableSet to store numbers. Of course, this being Objective C, I have to use NSNumber objects.

There are certain number values I wish to query the set for from time to time, so I'm trying to declare NSNumbers for them.

Code:
NSNumber *KEY_UP = [NSNumber numberWithUnsignedInt:NSUpArrowFunctionKey];
NSNumber *KEY_DOWN = [NSNumber numberWithUnsignedInt:NSDownArrowFunctionKey];
...

This does not work though. I get "Initializer element is not constant" errors for each line.

I tried moving the constants to a separate header and implementation file, to get something like this:

Code:
//codes.h
extern NSNumber * const KEY_UP;
extern NSNumber * const KEY_DOWN;
...

Code:
// codes.m
NSNumber * const KEY_UP
  = [NSNumber numberWithUnsignedInt:NSUpArrowFunctionKey];
NSNumber * const KEY_DOWN
  = [NSNumber numberWithUnsignedInt:NSDownArrowFunctionKey];
...

...And then I import codes.h in the file I'm going to be using with them. I still get the same errors. Mad
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #2
Correct, you can't execute code like +[NSNumber numberWithUnsignedInt:] outside the context of a function. If you really need constant NSNumbers like that, you'll have to call some function in that file to initialize them at startup. You're likely better off just using the existing primitive constants and dealing with creating a new NSNumber when you want to add to the set, and getting its -intValue when you want to retrieve one.
Quote this message in a reply
Member
Posts: 35
Joined: 2009.10
Post: #3
So if I want to check for a specific value, do I have to create a new NSNumber ever time?

Code:
// I'm also not quite sure what I should call on the temporary number to make sure it's garbage collected.
[myset containsObject:[[NSNumber numberWithUnsignedInt:NSUpArrowFunctionKey] autorelease]];
Quote this message in a reply
Member
Posts: 245
Joined: 2005.11
Post: #4
No. You can create the NSNumbers once and then hang on to them. You declare the pointers as globals and then assign the objects to them in your class's initialize method.
Code:
//See Skorche's post for a corrected version
NSNumber *KEY_UP;
NSNumber *KEY_DOWN;

- (void) initialize
{
KEY_UP = [[NSNumber numberWithUnsignedInt:NSUpArrowFunctionKey] retain];
KEY_DOWN = [[NSNumber numberWithUnsignedInt:NSDownArrowFunctionKey] retain];
}
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #5
A couple of nitpicks with the above code:

Code:
NSNumber *KEY_UP;
NSNumber *KEY_DOWN;

+ (void) initialize // + not -
{
  static bool done = FALSE;
  if(!done){ // This method will be called again if you subclass the class and don't define a initialize method for the subclass
    KEY_UP = [[NSNumber numberWithUnsignedInt:NSUpArrowFunctionKey] retain];
    KEY_DOWN = [[NSNumber numberWithUnsignedInt:NSDownArrowFunctionKey] retain];
    done = TRUE;
  }
}

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
I wondered if that's thread safe, but it is. See comment atop http://opensource.apple.com/source/objc4...itialize.m
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  char array versus pointer to string constant question WhatMeWorry 7 7,368 Jan 30, 2007 12:26 PM
Last Post: bronxbomber92
  syntax for C++ initializer list? WhatMeWorry 6 8,619 Jun 21, 2006 10:25 AM
Last Post: NCarter
  constant sliding plane headache typer 2 2,129 Jan 6, 2004 11:15 PM
Last Post: AnotherJake