- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我已经创建了一个默认首选项 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/
我对 NSUserDefaults 的 standardUserDefaults 有疑问。standardUserDefaults 方法到底做了什么?是在初始化对象吗? 最佳答案 是或否。 NSUse
我的应用程序涉及用户能够拖动特定项目,例如音量 slider 和 UIImage View 。我的目标是能够保存项目的位置,以便用户在重新启动后不必再次拖动项目。不幸的是,我在使用“保存 CGRect
有谁知道通过 NSLog 转储 NSUserDefaults 的 standardUserDefaults 的快速方法?这是我的: NSLog(@"NSUserDefaults dump: %@",
我的主菜单 (MainMenu.xib) 中有一个名为“Word Wrap”的 NSMenuItem。它的值绑定(bind)到我的共享用户默认 Controller ,也在 XIB 中实例化。选中时它
App Programming Guide for tvOS简要说明: Apple TV上没有用于应用程序的持久本地存储。这意味着为新的Apple TV开发的每个应用程序都必须能够在iCloud中存储
苹果的文档说 NSUserDefaults temporarily disables sudden termination to prevent process killing between the
我使用 NSUserDefaults 来存储一些东西。 它工作正常,但只有在我重新启动应用程序后。 我使用:[首选项同步];我以为它会立即保存数据,但首选项保持为空。 如果您有任何想法或已经处理过它,
在有人说这个问题之前已经被问过很多次之前,我已经浏览了大约 20 个不同的答案,并尝试了我发现的所有内容。尽管如此,我大约 5 天前才开始使用 Objective C,所以可能有一些非常简单的解决方案
我试图在应用程序第一次启动时显示警报。如果他们稍后进入设置页面并希望再次看到它,我还想显示此警报。我想我可以在 NSUserDefaults 中设置一个 bool 值。我不太确定如何做到这一点(假设这
在我的 viewWillLoad: 方法中,我目前正在执行以下操作: - (void)viewWillAppear:(BOOL)animated { NSUserDefaults *defaul
我将一个整数值传递给 NSUserDefault 对象来存储,以便在我的应用程序加载时使用。我HAD它工作得很好,直到我尝试将该整数值切换为 float 。它导致了一大堆问题,所以我重新调整了我的方法
我在 Settings.bundle 中保存了一些设置,并且尝试在 application:didFinishLaunchingWithOptions 中使用它们,但在模拟器上首次运行时,通过按键访问
数组如何保存到 NSUserDefaults 中? 我有以下代码尝试存储 NSURL 数组 NSArray *temp = [[NSArray alloc] initWithArray:[mySing
NSUserDefaults 的同步方法何时以及为何失败?确保我的值实际写入并提交给 NSUserDefaults 的最佳方法是什么,这样我在应用程序重新启动后恢复状态就不会遇到任何问题? 最佳答案
我对 NSUserDefaults 有疑问,并且不太明白发生了什么。 我的应用程序有 5 个级别,每个级别都与 NSUserDefaults 执行完全相同的操作(检索级别默认值,在用户玩该级别时更改值
我能够使用 NSUserDefaults 存储、检索和删除值。我无法成功找到 NSUserDefaults 在 iPhone 上的物理存储位置?我猜它应该是 plist 文件,但不确定。有谁知道是否可
谁能告诉我 NSUserDefaults 的最大大小。意味着我们可以存储在用户默认值中的对象或基元。例如 10 MB 等。 谢谢 最佳答案 不,除了设备本身的存储容量之外,NSUserDefaults
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: How can I reset the NSUserDefaults data in the iPhone simu
每次向 plist 写入任何内容时,我都会使用 [[NSUserDefaults standardUserDefaults] Synchronize] 。这太过分了吗?或者这样做会产生不良影响吗? 最
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:@"xxxxxxxx" fo
我是一名优秀的程序员,十分优秀!