static NSDictionary* const letterValues = @{ … } in a method does not compile

后端 未结 4 1452
南方客
南方客 2021-02-05 13:20

In a word game for iPhone:

\"app

I\'m trying to use the following code in my custom view Tile.

相关标签:
4条回答
  • 2021-02-05 13:31

    You can use static, but the assignment can't be made on the same line. Try this:

    - (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 @{<key> : <value>} syntax is translated by the compiler into an Objective-C method ([[NSPlaceholderDictionary alloc] initWithObjects:forKeys:count:]), which cannot be resolved at compile-time.

    0 讨论(0)
  • 2021-02-05 13:31

    Another alternative is using the Macro Approach:

    Macro (The Easiest) Approach (2020)

    #define kScreenNames @{ \
            @"HOME":                     @"Home Page", \
            @"SEARCH":                   @"Search Page", \
            @"MYLISTS":                  @"My List", \
            @"MYACCOUNT":                @"My Aaccount" \
    }
    

    it's short and elegant.

    Then, you can use it like any other NSDictionary.

    I hope this will help someone on the planet.

    Best Regards

    0 讨论(0)
  • You can only set a static variable during initialization with a constant. @{} creates an object, thus 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 a check for nil instead of dispatch once, but that can cause issues when creating multiple tiles at the same time (via threads). dispatch_once implements the required locking.

    0 讨论(0)
  • 2021-02-05 13:53

    NSDictionary objects can't be created at compile time. However, if you need a static object, you can create one. You can, for example, use the initialize method, like this:

    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 there to prevent multiple calls of your code in MyClass subclasses.

    0 讨论(0)
提交回复
热议问题