gpt4 book ai didi

ios - 通过 plist 覆盖 NSUserDefaults 值

转载 作者:搜寻专家 更新时间:2023-11-01 05:43:10 26 4
gpt4 key购买 nike

我已经创建了一个默认首选项 plist 文件,当应用程序启动时,我注册了这些默认值。但是我允许用户更改单个设置,除了更改每个单独的设置之外,它几乎更改了我注册的所有设置。基本上,我允许他们更改几乎所有其他存储设置的“主题”。当用户确实选择了一个主题时,而不是为每个设置调用 setObject:forKey 并手动定义所选主题应该是什么,我想知道为它创建另一个 plist 文件是否明智每个主题。我想我可以简单地覆盖存储在键匹配的 NSUserDefaults 中的值。这样做时,我还可以更轻松地检测应用程序的设置何时与任何主题的设置相同,或者他们是否自定义了主题。我会简单地检测存储在 NSUserDefaults 中的值是否等于每个键的每个主题 plist 中存储的值,如果它们中的任何一个不同,我知道他们已经定制了它并且没有使用内置 -在主题中。如果我不使用 plist,我将不得不将每个存储的值与手动定义的值进行比较,因此在两个不同的位置定义该主题的默认值(我在他们选择主题时设置的位置和我检查的位置查看当前设置是否与可用主题的设置相同)。

如果这是一个合适的实现,如何使用存储在 plist 中的值覆盖NSUserDefaults中的现有值?如果不是,在这种情况下您会推荐什么?

最佳答案

请注意,设置是应用程序中的一个概念(存储和使用 UI textSettings),在设计时最好考虑从实际实现(保留在 .plists、数据库等)中抽象出来。

所有这些单独的值都由一个概念组合在一起,因此可以在您的项目中用一个类来表示。此类“总结”了与概念相关的实现细节。此逻辑与程序的其他部分隔离,当您需要更改它时,您的更改仅限于单个实体,因此每次更改都不太可能破坏您的代码的其余部分。

这个类可以这样实现:

/////////////
// TextSettings.h

#import <Foundation/Foundation.h>

@interface TextSettings : NSObject <NSCoding>

@property (nonatomic, strong) UIColor *mainColor;
@property (nonatomic, copy) UIFont *font;

+ (instancetype)defaultTextSettings;

@end

/////////////
// TextSettings.m

@implementation TextSettings

+ (instancetype)defaultTextSettings
{
TextSettings *textSettings = [[TextSettings alloc] init];
textSettings.font = [UIFont systemFontOfSize:14.0f];
textSettings.mainColor = [UIColor whiteColor];
return textSettings;
}

#pragma mark - NSCoding

// Read more about NSCoding on: http://nshipster.com/nscoding/

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
_font = [aDecoder decodeObjectForKey:@"_font"];
_mainColor = [aDecoder decodeObjectForKey:@"_mainColor"];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.font forKey:@"_font"];
[aCoder encodeObject:self.mainColor forKey:@"_mainColor"];
}

#pragma mark - Equality

- (BOOL)isEqual:(id)object
{
if (object == nil) {
return NO;
}

if ([object isKindOfClass:[self class]] == NO) {
return NO;
}

TextSettings *otherTextSettings = object;

return [self.font isEqual:otherTextSettings.font] && [self.mainColor isEqual:otherTextSettings.mainColor];
}

// You must override -hash if you override -isEqual
- (NSUInteger)hash
{
return self.class.hash ^ self.font.hash ^ self.mainColor.hash;
}

@end

当你有这样一个对象时,你可以:

  • 轻松测试它们是否相等
  • 轻松归档和取消归档(序列化和反序列化)它们

平等测试

// TextSettings *myTextSettings
if ([myTextSettings isEqual:[TextSettings defaultTextSettings]]) {
// User didn't change the textSettings...
}
else {
// User changed the textSettings!
}

序列化/反序列化

// In a controller responsible for displaying something according to textSettings.
// textSettings (self.textSettings) is a @property in this controller.
- (void)saveCurrentTextSettings
{
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.textSettings];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"currentTextSettings"];
}

- (void)loadTextSettings
{
NSData *data = [[NSUserDefaults standardUserDefaults] dataForKey:@"currentTextSettings"];
self.textSettings = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

差不多就这些了。<​​/p>

当您要向 TextSettings 添加新字段时,您必须 (1) 将它们声明为 @properties,(2) 添加检查 -isEqual:-hash 实现和 (3) 添加解压/归档代码到 -encodeWithCoder-initWithCoder

太过分了!你可能会说,但我会说不——这不算矫枉过正。绝对比在 NSUserDefaults 中搜索和比较单个值要好。


更新:

将其用作普通设置:

// Called when user chooses new value
- (void)userDidChooseFont:(UIFont *)font
{
self.textSettings.font = font;
[self saveTextSettings];
}

- (void)saveTextSettings
{
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.textSettings];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"textSettings"];
}

关于ios - 通过 plist 覆盖 NSUserDefaults 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25343173/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com