我有一个符合NSCoding协议的简单对象.
import Foundation
class JobCategory: NSObject, NSCoding {
var id: Int
var name: String
var URLString: String
init(id: Int, name: String, URLString: String) {
self.id = id
self.name = name
self.URLString = URLString
}
// MARK: - NSCoding
required init(coder aDecoder: NSCoder) {
id = aDecoder.decodeObject(forKey: "id") as? Int ?? aDecoder.decodeInteger(forKey: "id")
name = aDecoder.decodeObject(forKey: "name") as! String
URLString = aDecoder.decodeObject(forKey: "URLString") as! String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(name, forKey: "name")
aCoder.encode(URLString, forKey: …Run Code Online (Sandbox Code Playgroud) 我使用的是[[NSUserDefaults standardUserDefaults] synchronize]每当我写什么plist中的时间.那有点矫枉过正吗?或者这样做有不良影响吗?
我有一个AppDelegate类+(void)initialize,我用它来注册一些默认值.这是我使用的代码:
+ (void)initialize {
NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys:@"NO", @"fooKey", @"YES", @"barKey", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
}
Run Code Online (Sandbox Code Playgroud)
我还创建了Preferences.xib,它包含几个NSButton显示首选项状态的复选框().它们NSUserDefaultsController与相同的键绑定(在这种情况下为fooKey和barKey).每次我启动应用程序并更改"默认值"时,它们都会在下次应用程序启动时恢复.
有没有办法在不覆盖现有值的情况下注册"默认默认值"?也许每次我构建并启动一个应用程序时,它的首选项文件正在重新创建?也许我应该从NSUserDefaultsController首选项窗口控制器中的一些自定义代码中取消绑定复选框并维护键的值?
我想听听您为维护用户默认值而选择的实现.
我正在使用Mac OS X 10.6.2和XCode 3.2.1
我有一个名为soundSwitch的开关,我正在使用用户默认值保存按钮的状态:
@IBAction func soundsChanged(sender: AnyObject) {
if soundSwitch.on{
defaults.setBool(true, forKey: "SoundActive")
print("Sound ON")
}else{
defaults.setBool(false, forKey: "SoundActive")
print("Sound OFF")
}
}
Run Code Online (Sandbox Code Playgroud)
当前,当用户首次启动应用程序时,实际默认值最初为false.
如果用户首次启动应用程序并且尚未配置它,我如何将默认值实现为true.
我在Objective-C中看过方法,但在Swift中没有.从我所看到的你可以在app中委托一些方法,或者在plist文件中.我该怎么办?
使用NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];,
我使用调用BOOL boolFromPrefs = [defaults boolForKey:@"theBoolKey"];来获取保存的BOOL值.
如果未找到密钥,则返回NO(boolForKey的默认行为).
但是...... NO可以是一个保存的设置.同样的事情intForKey
那么在尝试获取其值之前,如何测试密钥是否存在?
有时,但并非总是(我已经有一点工作),app/extension处于一种状态,我无法读取我的应用程序组在我的随播应用程序和我的应用程序扩展之间设置的标志.不知道它是如何处于这种状态或为什么值不同,但它对我的应用程序至关重要,它们始终是同步的.
Companion app viewDidLoad:
NSUserDefaults *myAppSettings = [[NSUserDefaults alloc] initWithSuiteName:@"group.myapp"];
.....
[myAppSettings setBool:true forKey:@"myBool"];
[myAppSettings synchronize];
NSLog([myAppSettings boolForKey:@"myBool"] ? @"Companion app - bool TRUE" : @"Companion app - bool FALSE");
Run Code Online (Sandbox Code Playgroud)
应用扩展程序viewDidLoad
NSUserDefaults *myAppSettings = [[NSUserDefaults alloc] initWithSuiteName:@"group.myapp"];
[myAppSettings synchronize];
NSLog([myAppSettings boolForKey:@"myBool"] ? @"App extension app - bool TRUE" : @"App extension - bool FALSE");
Run Code Online (Sandbox Code Playgroud)
控制台输出
Companion app - bool TRUE
App extension - bool FALSE
Run Code Online (Sandbox Code Playgroud)
我也会在我的同伴应用程序进入后台之前进行同步.我在门户网站等设置了我的应用程序组
我究竟做错了什么?
编辑
显然其他人也有这个问题:https: //devforums.apple.com/message/977151#977151
"我认为这目前非常糟糕.
有时数据共享起作用,然后进行更改,并且窗口小部件突然无法再看到共享数据(在模拟器和设备上).
烦人并希望它在下一个测试版中更加可靠!"
编辑2 看起来另一个人也报告了这个问题: …
我有一个使用[NSUserDefaults standardUserDefaults]存储会话信息的应用程序.通常,此信息会在应用启动时检查,并在应用退出时更新.我发现它似乎在iOS 8中不可靠.
我目前正在iPad 2上进行测试,但如果需要,我可以在其他设备上进行测试.
有些时候,退出之前写入的数据不会在应用程序启动时持续存在.同样,在退出之前删除的键有时在启动后似乎存在.
我编写了以下示例,试图说明问题:
- (void)viewDidLoad
{
[super viewDidLoad];
NSData *_dataArchive = [[NSUserDefaults standardUserDefaults]
objectForKey:@"Session"];
NSLog(@"Value at launch - %@", _dataArchive);
NSString *testString = @"TESTSTRING";
[[NSUserDefaults standardUserDefaults] setObject:testString
forKey:@"Session"];
[[NSUserDefaults standardUserDefaults] synchronize];
_dataArchive = [[NSUserDefaults standardUserDefaults]
objectForKey:@"Session"];
NSLog(@"Value after adding data - %@", _dataArchive);
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"Session"];
[[NSUserDefaults standardUserDefaults] synchronize];
_dataArchive = [[NSUserDefaults standardUserDefaults]
objectForKey:@"Session"];
NSLog(@"Value before exit - %@", _dataArchive);
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
运行上面的代码,我(通常)得到下面的输出(这是我所期望的):
Value at launch - (null)
Value after adding data - TESTSTRING
Value after …Run Code Online (Sandbox Code Playgroud) 在开始之前,我应该告诉你,这只发生在iOS 5.1中.在最近的更新之前,这从未发生过,并且它仍然不会发生在任何其他版本上.那就是说,这是正在发生的事情.
当用户退出我的应用程序时,发生的一件事就是NSUserDefaults删除了所有内容.而不是手动删除我可能添加到用户默认值的每个键,我只是NSUserDefaults使用此SO问题中建议的方法完全删除所有键:
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
Run Code Online (Sandbox Code Playgroud)
然而,似乎发生了什么,每次我尝试创建一个UIWebView删除后NSUserDefaults,我得到一个EXC_CRASH (SIGABRT).当我打电话时发生了崩溃[[UIWebView alloc] initWithFrame:frame].奇怪吧?完全退出并重新打开应用程序可以UIWebView再次创建s.
所以,我设法找出删除默认值会导致UIWebView问题,但可以肯定的是,我添加了一个符号断点-[NSUserDefaults setObject:forKey:].
![- [NSUserDefaults setObject:forKey:]断点](https://i.stack.imgur.com/0ODbq.png)
创建UIWebView确实会触发断点.
浏览崩溃日志给出了例外原因:
-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: WebKitLocalStorageDatabasePathPreferenceKey)
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪的开始:
0 CoreFoundation 0x3340688f __exceptionPreprocess + 163
1 libobjc.A.dylib 0x37bd4259 objc_exception_throw + 33
2 CoreFoundation 0x33406789 +[NSException raise:format:] + 1
3 CoreFoundation 0x334067ab +[NSException raise:format:] + 35 …Run Code Online (Sandbox Code Playgroud) 我有这个代码UserDefaults从应用程序中删除所有数据:
let domain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: domain)
print(Array(UserDefaults.standard.dictionaryRepresentation().keys).count)
Run Code Online (Sandbox Code Playgroud)
但是我10从印刷线上得到了.不应该0吗?
我需要将一个字符串从App委托传递到我的初始视图控制器,有人可以列出我最好的方法,我也尝试使用NS用户默认值保存和检索,但我没有正常工作.
nsuserdefaults ×10
ios ×6
objective-c ×4
iphone ×3
swift ×3
ios8 ×2
cocoa ×1
cocoa-touch ×1
key-value ×1
nscoding ×1
preferences ×1
swift3 ×1
uiswitch ×1
uiwebview ×1
xcode ×1