在iOS上访问NSUserDefaults被认为是便宜的吗?

时间:2016-01-19 21:51:49

标签: ios nsuserdefaults

简而言之:它快/便宜吗?将NSUserDefaults中的值存储在内存中以便更快地访问是否有意义?

更长:说,我有大量的值要从NSUserDefaults存储和读取;需要经常访问(读取)这些值。

在下面的代码片段中,我初始化一个私有存储属性,并使其与相应的NSUserDefaults值保持同步 - 所以当我需要读取它时,我会读取该属性。

如果直接读取默认值实际上很快,我显然会删除私有财产。但我不确定。它快吗?

.synchronize()

澄清未来的读者:问题是关于阅读,而不是写作/同步,这是(如答案中所指出的)不快也不便宜。

在设置器中调用

synchronizing是有正当理由的 - 在我的具体情况下,让它立即同步很重要,所以我牺牲性能来保持逻辑完整性。在一般情况下,您应该考虑是否需要调用它 - 或让系统选择适当的时间进行编写。

..事实上,现在我看着它,我看到保留存储的属性,因为它在片段中,将提供逻辑完整性(只要从其他地方访问通过getter发生,而不是直接来自userDefaults )。所以我也可以在这里避免#include <stdio.h> #include <stdlib.h> typedef enum { POSITION = 0, COLOR, NORMAL, TEXCOORD0 } vert_attrib_type; void vert_attrib_type_print(vert_attrib_type type); typedef struct { vert_attrib_type type; size_t count; size_t attrib_size; } vert_attrib; typedef struct { vert_attrib* attributes; size_t count; size_t vert_size; } vert_layout; vert_attrib* vert_attrib_new(vert_attrib_type type, size_t count) { vert_attrib* out = calloc(1, sizeof(vert_attrib)); out->type = type; out->count = count; out->attrib_size = out->count * sizeof(float); return out; } void vert_attrib_print(vert_attrib* a) { vert_attrib_type_print(a->type); } vert_layout* vert_layout_new(vert_attrib* attributes, size_t count) { vert_layout* out = calloc(1, sizeof(vert_layout)); out->attributes = calloc(1, sizeof(vert_attrib) * count); for (size_t i = 0; i < count; i++) { out->attributes[i] = attributes[i]; out->vert_size += attributes[i].attrib_size; } return out; } int main(int argc, char* argv[]) { printf("argc:%s\n", argv[argc - 1]); vert_attrib** attribs = calloc(1, sizeof(vert_attrib) * 3); attribs[0] = vert_attrib_new(POSITION, 3); attribs[1] = vert_attrib_new(COLOR, 4); attribs[2] = vert_attrib_new(TEXCOORD0, 2); for (size_t i = 0; i < 3; i++) { vert_attrib_print(attribs[i]); } vert_layout* l = vert_layout_new(*attribs, 4); free(attribs); free(l->attributes); free(l); return 0; } void vert_attrib_type_print(vert_attrib_type t) { switch (t) { case POSITION: printf("Position\n"); break; case COLOR: printf("Color\n"); break; case NORMAL: printf("Normal\n"); break; case TEXCOORD0: printf("TexCoord 0\n"); break; } }

4 个答案:

答案 0 :(得分:8)

阅读很便宜。有一个慷慨的缓存,一切都发生在RAM中。变异相对便宜,但系统仍然必须定期将内容存储到非易失性存储器(闪存上的.plist文件)。

显式同步并不便宜。它耗费时间和精力。

因此对于读取它很好,但是通过大量写入,我仍然可以在单独的容器中进行,并且仅在需要时进行序列化。

答案 1 :(得分:2)

它不太可能产生重大的性能影响,但您可以使用Instruments自行分析,以确保性能影响可以忽略不计。

答案 2 :(得分:1)

I made some performance tests with Instruments as @mipadi has suggested the past year and my conclusion was there is no substantial difference.

As I pointed out in a comment above, it's very important to detect which of those NSUserDefaults writes we want to be done straightaway. Just in those particular cases use synchronize方法,否则请让iOS处理该工作以获得更好的效果。

答案 3 :(得分:0)

除非您将NSUserDefaults用作数据库,否则一切正常。 synchronize()将写入完整的plist文件,因此如果存储兆字节的数据,然后同步很多,性能和/或电池寿命将受到影响。

但请查看此问题:How often are NSUserDefaults synchronised?

一个有趣的细节是,当您的应用程序终止时,将写入用户默认值。如果你的程序在更改NSUserdefaults后立即崩溃,有人可能会试验会发生什么。如果算作&#34;终止&#34;。