静态NSDictionary * const的letterValues = @ {…}在一个方法不会编译
在iPhone的文字游戏中 :
我想在我的自定义视图Tile.m中使用下面的代码:
- (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]; }
不幸的是,这给了我编译错误初始化元素不是一个编译时常量 ,我必须删除static
关键字来获取我的应用程序在Xcode(这里全屏 )编译:
我想我正确地初始化NSDictionary
– 通过使用新的Objective-C文字语法。
但为什么我不能在这里使用static
?
我认为这是适当的,以确保我的letterValues
常量只设置一次?
你只能在初始化时用一个常量来设置一个静态variables。 @ {}创build一个对象,因此不是一个常量。
做这个,而不是:
- (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, }; }); ... }
这里的其他一些答案build议检查一次,而不是一次调度,但这可能会导致在同一时间(通过线程)创build多个磁贴时出现问题。 dispatch_once实现所需的locking。
您可以使用静态,但不能在同一行上进行分配。 尝试这个:
- (void)awakeFromNib { [super awakeFromNib]; static NSDictionary* letterValues = nil; if (!letterValues) { letterValues = @{@"A": @1, @"B": @4, @"C": @4, // ... @"X": @8, @"Y": @3, @"Z": @10}; } ... }
原因在于编译器将@{<key> : <value>}
语法翻译成Objective-C方法( [[NSPlaceholderDictionary alloc] initWithObjects:forKeys:count:]
),在编译时无法parsing。
NSDictionary
对象不能在编译时创build。 但是,如果你需要一个静态对象,你可以创build一个。 例如,您可以使用initialize
方法,如下所示:
static NSDictionary* letterValues; + (void)initialize { if (self == [MyClass class]) { letterValues = @{ @"A": @1, @"B": @4, @"C": @4, @"X": @8, @"Y": @3, @"Z": @10, }; } }
if语句可以防止在MyClass
子类中多次调用您的代码。