Static NSDictionary * const letterValues ​​= @ {.....} in the method does not compile

In game game for iPhone :

app screenshot

I am trying to use the following code in my custom Tile.m view :

- (void)awakeFromNib { [super awakeFromNib]; static NSDictionary* const letterValues = @{ @"A": @1, @"B": @4, @"C": @4, // ... @"X": @8, @"Y": @3, @"Z": @10, }; NSString* randomLetter = [kLetters substringWithRange:[kLetters rangeOfComposedCharacterSequenceAtIndex:arc4random_uniform(kLetters.length)]]; int letterValue = [letterValues[randomLetter] integerValue]; _smallLetter.text = _bigLetter.text = randomLetter; _smallValue.text = _bigValue.text = [NSString stringWithFormat:@"%d", letterValue]; } 

Unfortunately, this gives me a compilation error. The Initializer element is not a compile-time constant , and I need to remove the static to get my application in Xcode (here in full screen ):

Xcode screenshot

I think I'm initializing NSDictionary - with the new Objective-C Literals syntax .

But why can't I use static here?

I thought it would be appropriate for my letterValues constant letterValues be set only once?

+8
ios static objective-c const nsdictionary
source share
3 answers

You can set a static variable during initialization with a constant. @ {} creates an object, not a constant.

Do this instead:

 - (void)awakeFromNib { [super awakeFromNib]; static NSDictionary* letterValues = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ letterValues = @{ @"A": @1, @"B": @4, @"C": @4, // ... @"X": @8, @"Y": @3, @"Z": @10, }; }); ... } 

Some other answers here suggest checking for nil instead of sending once, but this can cause problems while creating multiple fragments at the same time (via streams). dispatch_once implements the required lock.

+33
source share

You can use static, but the assignment cannot be performed on one line. Try the following:

 - (void)awakeFromNib { [super awakeFromNib]; static NSDictionary* letterValues = nil; if (!letterValues) { letterValues = @{@"A": @1, @"B": @4, @"C": @4, // ... @"X": @8, @"Y": @3, @"Z": @10}; } ... } 

The reason is that the syntax @{<key> : <value>} converted by the compiler to the Objective-C method [[NSPlaceholderDictionary alloc] initWithObjects:forKeys:count:] ), which cannot be resolved at compile time.

+4
source share

NSDictionary objects cannot be created at compile time. However, if you need a static object, you can create one. For example, you can use the initialize method, for example:

 static NSDictionary* letterValues; + (void)initialize { if (self == [MyClass class]) { letterValues = @{ @"A": @1, @"B": @4, @"C": @4, @"X": @8, @"Y": @3, @"Z": @10, }; } } 

The if statement is designed to prevent multiple calls to your code in subclasses of MyClass .

+1
source share

All Articles