Ale*_*ber 13 static const objective-c nsdictionary ios

我正在尝试在自定义视图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];
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这给了我编译错误Initializer元素不是编译时常量,我必须删除static关键字以使我的应用程序在Xcode中编译(这里全屏):

我认为我NSDictionary正确地初始化- 使用新的Objective-C Literals语法.
但为什么我不能static在这里使用?
我认为在这里确保我的letterValues常量只设置一次是合适的吗?
Dav*_*ood 41
您只能在初始化期间使用常量设置静态变量.@ {}创建一个对象,因此不是常量.
改为:
- (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,
};
});
...
}
Run Code Online (Sandbox Code Playgroud)
这里的一些其他答案建议检查nil而不是一次调度,但这可能会在同时创建多个tile时(通过线程)导致问题.dispatch_once实现所需的锁定.
您可以使用静态,但不能在同一行上进行分配.试试这个:
- (void)awakeFromNib {
[super awakeFromNib];
static NSDictionary* letterValues = nil;
if (!letterValues) {
letterValues = @{@"A": @1,
@"B": @4,
@"C": @4,
// ...
@"X": @8,
@"Y": @3,
@"Z": @10};
}
...
}
Run Code Online (Sandbox Code Playgroud)
原因是@{<key> : <value>}编译器将语法转换为Objective-C方法([[NSPlaceholderDictionary alloc] initWithObjects:forKeys:count:]),这在编译时无法解析.
另一种选择是使用宏观方法:
#define kScreenNames @{ \
@"HOME": @"Home Page", \
@"SEARCH": @"Search Page", \
@"MYLISTS": @"My List", \
@"MYACCOUNT": @"My Aaccount" \
}
Run Code Online (Sandbox Code Playgroud)
它简短而优雅。
然后,您可以像任何其他 NSDictionary 一样使用它。
我希望这能帮助地球上的某个人。
最好的
| 归档时间: |
|
| 查看次数: |
24866 次 |
| 最近记录: |