有人可以解释一下 NSUserDefaults 中的搜索列表功能吗?
我对 NSUserDefaults 中的搜索列表功能感到困惑。 类引用介绍了 < code>standardUserDefaults 类方法,它设置一个由五个域组成的标准搜索列表。该方法的文档还暗示可以更改此搜索列表(粗体是我添加的):
即使再次调用此方法,对标准搜索列表的后续修改仍然有效 - 仅在第一次调用此方法时才保证搜索列表是标准的。
我们还看一下 init
的文档:
返回值:已初始化的 NSUserDefaults 对象,其参数和注册域已设置。
讨论:此方法不会在搜索列表中放入任何内容。
根据我的理解,这是一个矛盾:搜索列表要么为空,要么包含参数和注册域的条目。
无论如何,我做了一些实验:
NSUserDefaults* standardUserDefaults = [NSUserDefaults standardUserDefaults];
// We get nil, which is expected
NSLog(@"test 1: expecting nil, getting %@", [standardUserDefaults objectForKey:@"foo"]);
NSDictionary* registrationDomainDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:42] forKey:@"foo"];
[standardUserDefaults registerDefaults:registrationDomainDefaults];
// We get 42, which is expected
NSLog(@"test 2: expecting 42, getting %@", [standardUserDefaults objectForKey:@"foo"]);
[standardUserDefaults removeSuiteNamed:NSRegistrationDomain];
[standardUserDefaults removeVolatileDomainForName:NSRegistrationDomain];
// Here we get 42!
NSLog(@"test 3: expecting nil, getting %@", [standardUserDefaults objectForKey:@"foo"]);
NSUserDefaults* myUserDefaults = [[NSUserDefaults alloc] init];
// Here we also get 42!
NSLog(@"test 4: expecting nil, getting %@", [myUserDefaults objectForKey:@"foo"]);
[myUserDefaults removeSuiteNamed:NSRegistrationDomain];
[myUserDefaults removeVolatileDomainForName:NSRegistrationDomain];
// We still get 42 *sigh*
NSLog(@"test 5: expecting nil, getting %@", [myUserDefaults objectForKey:@"foo"]);
如您所见,我试图通过调用 removeSuiteNamed:
和 removeVolatileDomainForName: 从搜索列表中删除
。这不起作用,至少在我运行测试的 iOS 上不起作用,但我认为它在 Mac OS X 上是相同的。所以这些是我的问题:NSRegistrationDomain
- 在 iOS 上,有没有办法从搜索
NSUserDefaults
对象的列表?请注意,它不一定是standardUserDefaults
返回的对象,我很乐意创建自己的对象。如果重要的话:我对摆脱NSRegistrationDomain
特别感兴趣。 - 如果上述答案是“否”,我们是否可以说这五个标准域只是“不可变的”,并且
NSUserDefaults
中有关添加/删除套件和持久/易失性域的所有内容都是关于用户定义的域? - 有没有办法找出 NSUserDefaults 对象的搜索列表中的内容?
我怀疑我已经知道答案(不、是、否),但至少我正在寻找有更多经验的人来证实我的怀疑。
I am confused about the search list feature in NSUserDefaults
. The class reference says about the standardUserDefaults
class method that it sets up a standard search list consisting of five domains. The docs for that method also imply that this search list can be changed (boldness added by me):
Subsequent modifications to the standard search list remain in effect even when this method is invoked again—the search list is guaranteed to be standard only the first time this method is invoked.
Let's also look at the docs for init
:
Return Value: An initialized NSUserDefaults object whose argument and registration domains are already set up.
Discussion: This method does not put anything in the search list.
In my understanding this is a contradiction: Either the search list is empty, or it contains entries for the argument and registration domains.
Anyway, I did a bit of experimentation:
NSUserDefaults* standardUserDefaults = [NSUserDefaults standardUserDefaults];
// We get nil, which is expected
NSLog(@"test 1: expecting nil, getting %@", [standardUserDefaults objectForKey:@"foo"]);
NSDictionary* registrationDomainDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:42] forKey:@"foo"];
[standardUserDefaults registerDefaults:registrationDomainDefaults];
// We get 42, which is expected
NSLog(@"test 2: expecting 42, getting %@", [standardUserDefaults objectForKey:@"foo"]);
[standardUserDefaults removeSuiteNamed:NSRegistrationDomain];
[standardUserDefaults removeVolatileDomainForName:NSRegistrationDomain];
// Here we get 42!
NSLog(@"test 3: expecting nil, getting %@", [standardUserDefaults objectForKey:@"foo"]);
NSUserDefaults* myUserDefaults = [[NSUserDefaults alloc] init];
// Here we also get 42!
NSLog(@"test 4: expecting nil, getting %@", [myUserDefaults objectForKey:@"foo"]);
[myUserDefaults removeSuiteNamed:NSRegistrationDomain];
[myUserDefaults removeVolatileDomainForName:NSRegistrationDomain];
// We still get 42 *sigh*
NSLog(@"test 5: expecting nil, getting %@", [myUserDefaults objectForKey:@"foo"]);
As you can see, I am trying to remove NSRegistrationDomain
from the search list, by invoking both removeSuiteNamed:
and removeVolatileDomainForName:
. This does not work, at least not on iOS where I ran the tests, but I assume it's the same on Mac OS X. So these are my questions:
- On iOS, is there a way to remove one of the five standard domains from the search list of an
NSUserDefaults
object? Note that it does not necessarily have to be the object returned bystandardUserDefaults
, I would be happy to create my own object. In case it matters: I am particularly interested in getting rid ofNSRegistrationDomain
. - If the answer to the above is "no", can we say that the five standard domains are simply "immutable" and that all the stuff in
NSUserDefaults
about adding/removing suites and persistent/volatile domains is about user-defined domains? - Is there a way to find out what is in the search list of an
NSUserDefaults
object?
I suspect I already know the answers (no, yes, and no), but at least I am looking for someone with more experience to confirm my suspicions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要删除像
NSRegistrationDomain
这样的域,您应该使用removeVolatileDomainForName:
。但是,这不适用于NSRegistrationDomain
和NSArgumentDomain
。这两个不能去掉。尝试使用setVolatileDomain:forName:
注册您自己的域。您将能够删除这个。我相信,在 standardUserDefaults 的五个域中,您可以使用
removePersistentDomainForName:
删除您自己的域,并传递您的包标识符。但我还没有尝试过。由于
NSGlobalDomain
是持久性的,并且您只能将自己的包标识符传递给removePersistentDomainForName:
,因此我相信您无法删除NSGlobalDomain
。同样,这未经测试。我相信是这样,除了具有您的捆绑包标识符的持久域。
不,但使用
-volatileDomainNames
对于大多数用途来说应该足够了。To get rid of a domain like
NSRegistrationDomain
, you should useremoveVolatileDomainForName:
. However, this will not work withNSRegistrationDomain
andNSArgumentDomain
. These two cannot be removed. Try to register your own domain withsetVolatileDomain:forName:
instead. You'll be able to remove this one.I believe that in the five domains of the standardUserDefaults, you can remove your own domain with
removePersistentDomainForName:
, passing your bundle identifier. But I've not tried this out.Since
NSGlobalDomain
is persistent and you can only pass your own bundle identifier toremovePersistentDomainForName:
, I believe you can't removeNSGlobalDomain
. Again, this is untested.I believe so, except for the persistent domain with your bundle identifier.
No, but using
-volatileDomainNames
should be sufficient for most purposes.尝试在修改后立即调用 [myuserDefaults Synchronize]
try calling [myuserDefaults synchronize] right after your modifications