NSUserDefaults NSMutable 数组未在会话之间保存

Posted

技术标签:

【中文标题】NSUserDefaults NSMutable 数组未在会话之间保存【英文标题】:NSUserDefaults NSMutable Array Not Saving Between Sessions 【发布时间】:2010-11-08 19:34:44 【问题描述】:

我有一个 NSMutableArray 存储在 NSUserDefaults 中。可变数组已正确编辑,编辑结果可以通过以下方式查看:

NSLog(@"%@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);

但是,当我退出并重新启动应用程序时,用户默认会恢复到原来的形式。

我尝试通过运行此方法强制同步来保存状态:

-(void) saveUserDefaults
if([[NSUserDefaults standardUserDefaults] synchronize])
    NSLog(@"Defaults saved");
else
    NSLog(@"Defaults save failed");


NSLog(@"%@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);

是否有任何想法为什么这可能无法保存?

我在第一次运行应用程序时使用此代码设置用户默认数组:

// Check if first time run
if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"isFirstRun"] isEqualToString:@"no"]) 

    // Not first run, NSUserDefault arrays are already set
else 
    // First Run of Program 
    // Mark for future
    [[NSUserDefaults standardUserDefaults] setObject:@"no" forKey:@"isFirstRun"];


    designerArray = [[NSMutableArray alloc] initWithObjects: @"Alberta Ferretti", @"Alberto Fermani", @"Alejandro Ingelmo", @"Alexander McQueen", @"Alexander Wang", @"Ann Demeulemeester", @"Anne Klein", @"Aquatalia", @"Anya Hindmarch", @"Ash", @"Badgley Mischka Platinum Label", @"Balenciaga ", @"BCBGMAXAZRIA", @"BC Studio", @"Be & D", @"Belle by Sigerson Morrison", @"Bettye Muller ", @"Beverly Feldman", @"Botkier", @"Bourne", @"Bottega Veneta", @"Brian Atwood", @"Burberry", @"Burberry Prorsum", @"Camilla Skovgaard", @"Candela", @"Carlos Falchi", @"Casadei ", @"Chie Mihara", @"Chloe", @"Christian Louboutin", @"Claudio Merazzi", @"Coach", @"Cole Haan", @"Comme des Garcons", @"Costume National", @"Cynthis Vincent", @"Delman ", @"Devi Kroell", @"Derek Lam", @"Diane von Furstenberg", @"Dior", @"Dolce & Gabbana", @"Dolce Vita", @"Donald J Pliner ", @"Donna Karan", @"Elie Tahari ", @"Elizabeth and James", @"Emilio Pucci", @"Emma Hope", @"Eric Javits", @"Fendi", @"Ferragamo ", @"Foley & Corinna", @"Frye ", @"Furla", @"Giuseppe Zanotti", @"Givenchy", @"Gucci", @"Halston Heritage", @"H by Hudson", @"Hobo International", @"House of Harlow 1960", @"Hunter", @"Jack Rogers", @"Jean Paul ", @"Jerome C. Rousseau", @"Jil Sander", @"Jimmy Choo", @"Joan & David", @"Joie", @"Jonathan Kelsey", @"Judith Leiber", @"Juicy Couture", @"Junya Watanabe", @"Kate Spade", @"Kooba", @"Kork-Ease ", @"Kors Michael Kors", @"L.A.M.B.", @"LD Tuttle", @"Le Silla", @"Lanvin", @"Lilly Pulitzer", @"Linea Pelle", @"Lockheart", @"Loeffler Randall", @"Longchamp", @"Luciano Padovan", @"Maison Martin Margiela", @"Maison Martin Margiela MM6", @"MANITOBAH MUKLUKS ", @"MANOLO BLAHNIK ", @"Marc by Marc Jacobs", @"Marc Jacobs", @"Marina Rinaldi", @"MATT BERNSON ", @"Max Kibardin", @"MCM", @"Melissa", @"Michael Kors", @"MICHAEL MICHAEL KORS", @"Milly", @"Miu Miu", @"Miss Sixty", @"Missoni", @"Modern Vintage", @"Moschino", @"Moschino Cheap and Chic", @"Nancy Gonzalez", @"Narcisco Rodriguez", @"Nina Ricci", @"Nicholas Kirkwood", @"Olivia Harris", @"Opening Ceremony", @"Oscar de la Renta", @"PATRICIA GREEN ", @"Pedro Garcia ", @"Philosophy by Alberta Ferretti", @"Pollini", @"Prada", @"Proenza Schouler", @"Pura Lopez",@"Rachel Comey ", @"Rag & Bone", @"Ralph Lauren", @"Rebecca Minkoff", @"Rene Caovilla ", @"Repetto", @"Robert Clergerie ", @"Rock & Republic", @"Rosegold", @"Rupert Sanderson", @"Salvatore Ferragamo", @"SAM EDELMAN ", @"Scorah Pattulo", @"See by Chloe", @"7 for all mankind ", @"Sergio Rossi", @"Sigerson Morrison", @"Stella McCartney ", @"Stephane Verdino", @"Steve Madden", @"Storksak", @"Stuart Weitzman", @"Studio Pollini", @"Taryn Rose", @"Thakoon", @"Theory", @"Tracy Reese", @"Tod's", @"TOMS ", @"Tory Burch", @"UGG Australia", @"Valentino", @"Vera Wang Lavender Label", @"Versace", @"Via Spiga", @"Vince Camuto", @"Yves Saint Laurent", @"Zac Posen", @"Zagliani", @"-", nil];

    [[NSUserDefaults standardUserDefaults] setObject:designerArray forKey:@"designerArray"];

    shoeStyles = [[NSMutableArray alloc] initWithObjects: @"Ankle Strap", @"Ballet Flat", @"Boot", @"Bootie", @"Buckle Strap", @"Caged", @"Cowboy Boot", @"D'Orsay", @"Espadrille", @"Flat", @"Flat Sandal", @"Lace Up Boot",@"Mary Jane", @"Mid Calf Boot", @"Open Toe Flat", @"Open Toe Pump", @"Platform", @"Strappy Sandal", @"Thigh High Boot", @"Rain Boot", @"Sling Back", @"T-Strap", @"-", nil];

    [[NSUserDefaults standardUserDefaults] setObject:shoeStyles forKey:@"shoeStyles"];

【问题讨论】:

您可能需要考虑将您的设计师和鞋型数组存储为 plist 文件,而不是将它们硬编码到您的程序中。 为什么?它们是可编辑的,并且可以很好地分配给 NSUserDefaults。我不知道为什么人们一直使用 plist... 人们经常喜欢使用 plist 而不是硬编码数组的原因是为了避免在您需要更改它们时代码中的潜在损坏,或者如果您想要更改源代码,您可以轻松地执行 HTTP get 从某处获取 plist 并轻松导入。 "HTTP get to grab the plist" - 你在哪里可以找到 plist 使用?我认为 plist 的格式很痛苦。我宁愿格式化一个逗号分隔的数组。 @Bryan,如果“可编辑”是指每次更改都必须重新编译应用程序,那么是的,这是可编辑的。将应用程序的静态数据放在单独的文件中(我建议使用 plist,因为它们与 Cocoa 兼容)从长远来看更容易维护。 Hard-coding 通常被认为是一种反模式。 【参考方案1】:

您的意思是您将默认值设置为 NSMutableArray,然后如果您在默认值之外更改可变数组,您会丢失更改?

如果是这样,默认值可能没有注意到您已经更改了数组。您需要创建一个新数组并再次发送-setObject:forKey:(或使用相同的可变数组并发送-setObject:forKey:)。

顺便说一句,文档说你只能传递一个 NSArray。这并不意味着你不能传递 NSMutableArray,但你需要保持契约精神,不要改变你传入的数组。

【讨论】:

我不会在默认值之外更改可变数组。默认值已更改,当我记录 NSUserDefaults 的内容时,我看到了更改,但是当我退出并重新启动应用程序时,更改不会生效。此外,NSMutableArrays 的设置和检索都很好。 @Bryan:我忘记提到的一件事是你不需要做第一次运行的事情。您应该在应用程序启动期间的某个时间使用-registerDefaults:,然后在需要时进行更改。 developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/…【参考方案2】:

什么时候调用 saveUserDefaults?

我还建议只在方法内调用一次 [NSUserDefaults standardUserDefaults]。只需保留一个指向该对象的指针并一次又一次地使用它,如下所示:

<pre>NSMutableArray *designerArray = [[NSMutableArray alloc] initWithObjects: @"Alberta Ferretti" ...;</pre>

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [默认 setObject:designerArray forKey:@"designerArray"]; [默认同步];

我将上面的代码与您的设计器数组一起使用,它对我有用。

【讨论】:

那没有任何作用。问题是我在退出应用程序之前打印出默认值并且值是正确的(已更改)。但是当我退出并重新启动应用程序时,值保持不变。 上面的代码对我有用。由于您的应用程序中的值在退出之前看起来是正确的,但在下次启动时不会持续存在,这意味着您没有提交更改。你什么时候调用 saveUserDefaults()? 肯尼 - 有趣的是,通过将其添加到 saveUserDefaults 中它起作用了:[standardDefaults setObject:[standardDefaults objectForKey:@"designerArray"] forKey:@"designerArray"];【参考方案3】:

这对我有用。我几乎不得不将数组重新分配给它自己。

[standardDefaults setObject:[standardDefaults objectForKey:@"designerArray"] forKey:@"designerArray"];

【讨论】:

以上是关于NSUserDefaults NSMutable 数组未在会话之间保存的主要内容,如果未能解决你的问题,请参考以下文章

将 NSMutable 数组存储到 sqlite 数据库中

过滤自定义对象的 NSMutable 数组

如何将 NSString 值设置为 NSMutable 字典?

将对象添加到排序的 NSMutable 数组并回答索引路径

如何将 NSMutable 数组中的数据存储在 Core Data 中?

如何将NSMutable数组附加到现有文件中