该项目适用于ios 5.0。我设置了自动引用计数,无论如何,如果我写一个retain语句,我就无法编译代码。
我在一个函数中写了一个开关,因为我不想创建if和很多if else分支。
我的代码部分相对简单,似乎正确,但似乎只是:
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
switch (selectedRow) {
case 0://English
[userDefaults setObject:@"English" forKey:@"language"];
break;
case 1:// Deutsch
[userDefaults setObject:@"German" forKey:@"language"];
break;
case 2://Français
[userDefaults setObject:@"French" forKey:@"language"];
break;
case 3://Italiano
[userDefaults setObject:@"Italian" forKey:@"language"];
break;
case 4://Español
[userDefaults setObject:@"Spanish" forKey:@"language"];
break;
default:
break;
}
// flush:
[userDefaults synchronize];
在运行时我收到此消息: *** - [MyClass retain]:发送到解除分配的实例0x6e78580的消息 它会将XCode显示为某些案例分支的[userDefaults setObject行]的分隔线。
在某些地方,我在编译Switch时看到了编译,它将创建一个类。但我不确定使用哪种语言:Java,C#或Obj-C,因为我离开了我的类并且我正在执行switch类,它将释放userDefaults变量,这就是为什么取消分配userDefaults对象的原因。现在我不知道如何编写这个开关来工作,看起来像专业。我不想在每种情况下创建userDefaults变量并在那里刷新。唯一的解决方案是将此开关写入if-else?
这是有效的:
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
switch (selectedRow) {
case 0://English
{
[userDefaults setObject:@"English" forKey:@"language"];
}
break;
case 1:// Deutsch
{
[userDefaults setObject:@"German" forKey:@"language"];
}
break;
case 2://Français
{
[userDefaults setObject:@"French" forKey:@"language"];
}
break;
case 3://Italiano
{
[userDefaults setObject:@"Italian" forKey:@"language"];
}
break;
case 4://Español
{
[userDefaults setObject:@"Spanish" forKey:@"language"];
}
break;
default:
break;
}
// flush:
[userDefaults synchronize];
为什么?
不确定为什么它确实有效,但它再次崩溃了。 我已经在代码中移动了变量:
开关(selectedRow){
case 0://English
{
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"English" forKey:@"language"];
// flush:
[userDefaults synchronize];
}
break;
case 1:// Deutsch
{
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"German" forKey:@"language"];
// flush:
[userDefaults synchronize];
}
break;
case 2://Français
{
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"French" forKey:@"language"];
// flush:
[userDefaults synchronize];
}
break;
case 3://Italiano
{
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"Italian" forKey:@"language"];
// flush:
[userDefaults synchronize];
}
break;
case 4://Español
{
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"Spanish" forKey:@"language"];
// flush:
[userDefaults synchronize];
}
break;
default:
break;
}
再次坠毁,我来到这里检查答案:)
我看到了下面的建议:
NSArray * languages = [NSArray arrayWithObjects: @"English", @"German", @"French",@"Italian", @"Spanish", nil];
NSString * selectedLanguage = [languages objectAtIndex: selectedRow];
[[NSUserDefaults standardUserDefaults] setObject: selectedLanguage forKey:@"language"];
这次崩溃在同一条线上:
[[NSUserDefaults standardUserDefaults] setObject: selectedLanguage forKey:@"language"];
MyClass是一个UIViewContoller。我做了一个语言选择并按下一些按钮来导航1或2屏幕,我回来再次进行语言选择,它会崩溃,但并非总是如此。但是当它崩溃时总是在同一行并且总是出现相同的错误信息。
有什么
userDefaults setObject
导航?
遇到了真正的问题:比轻松找到解决方案
我写了:userDefaults setObject 我还写道:这是一个ARC项目,它在MyClass保留时失败,这不能是我的代码。
代码是带有操作表的语言选择。 如果我进行搜索,我会有下一个链接: EXC_BAD_ACCESS invoking a block
// [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@“language”options:NSKeyValueObservingOptionNew context:NULL];
删除了代码并且在切换代码之后移动了回调内容它解决了问题 - 不需要保留来执行回调:)
我已经投票支持所有人,并试图帮助我,并接受了最“漂亮”代码的解决方案。
由于
答案 0 :(得分:2)
此问题并非特定于Objective-C,而是特定于C / C ++。您可能需要查看this answer。
你的第一个代码的问题是Objective-C编译器做了一些与NSString
的实例化相关的魔术,这很可能导致上面链接的问题中描述的问题。简而言之:你需要在实例化局部变量的每个case
语句周围加上大括号,而@"something"
正是这样做的。
答案 1 :(得分:1)
部分答案:
在Objective-C switch-case语句中,如果你在一个case中声明一个ivar,你必须用大括号括起case,就像你在第二个例子中所做的那样(虽然我看过的例子是{{1}大括号内的语句。)
你的case语句没有声明变量,但NSUserDefaults可能在那里有效地创建了一个对象,使得括号成为必需的。 (编辑:正如starbugs在下面的回答中所说,当你写@“语言”时,你 实例化一个对象。)
所以,如果你的第二个例子有效,为什么不配合呢?它看起来如何不专业?特别是考虑到用于开关的额外支架是Objective-C的标准配置。
答案 2 :(得分:1)
不是您问题的答案,而是如何放弃switch
并使用:
NSArray * languages = [NSArray arrayWithObjects: @"English", @"German", @"French",
@"Italian", @"Spanish", nil];
NSString * selectedLanguage = [languages objectAtIndex: selectedRow];
[[NSUserDefaults standardUserDefaults] setObject: selectedLanguage forKey:@"language"];