有人可以解释一下 NSUserDefaults 中的搜索列表功能吗?

发布于 2025-01-02 06:27:58 字数 2411 浏览 3 评论 0原文

我对 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: 从搜索列表中删除 NSRegistrationDomain。这不起作用,至少在我运行测试的 iOS 上不起作用,但我认为它在 Mac OS X 上是相同的。所以这些是我的问题:

  1. 在 iOS 上,有没有办法从搜索 NSUserDefaults 对象的列表?请注意,它不一定是 standardUserDefaults 返回的对象,我很乐意创建自己的对象。如果重要的话:我对摆脱 NSRegistrationDomain 特别感兴趣。
  2. 如果上述答案是“否”,我们是否可以说这五个标准域只是“不可变的”,并且 NSUserDefaults 中有关添加/删除套件和持久/易失性域的所有内容都是关于用户定义的域?
  3. 有没有办法找出 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:

  1. 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 by standardUserDefaults, I would be happy to create my own object. In case it matters: I am particularly interested in getting rid of NSRegistrationDomain.
  2. 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?
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忱杏 2025-01-09 06:27:58
  1. 要删除像 NSRegistrationDomain 这样的域,您应该使用 removeVolatileDomainForName:。但是,这不适用于 NSRegistrationDomainNSArgumentDomain。这两个不能去掉。尝试使用 setVolatileDomain:forName: 注册您自己的域。您将能够删除这个。

    我相信,在 standardUserDefaults 的五个域中,您可以使用 removePersistentDomainForName: 删除您自己的域,并传递您的包标识符。但我还没有尝试过。

    由于 NSGlobalDomain 是持久性的,并且您只能将自己的包标识符传递给 removePersistentDomainForName:,因此我相信您无法删除 NSGlobalDomain。同样,这未经测试。

  2. 我相信是这样,除了具有您的捆绑包标识符的持久域。

  3. 不,但使用 -volatileDomainNames 对于大多数用途来说应该足够了。

  1. To get rid of a domain like NSRegistrationDomain, you should use removeVolatileDomainForName:. However, this will not work with NSRegistrationDomain and NSArgumentDomain. These two cannot be removed. Try to register your own domain with setVolatileDomain: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 to removePersistentDomainForName:, I believe you can't remove NSGlobalDomain. Again, this is untested.

  2. I believe so, except for the persistent domain with your bundle identifier.

  3. No, but using -volatileDomainNames should be sufficient for most purposes.

吾性傲以野 2025-01-09 06:27:58

尝试在修改后立即调用 [myuserDefaults Synchronize]

try calling [myuserDefaults synchronize] right after your modifications

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文