请看,设置是您的应用程序中的一个概念(存储和使用 UI 文本设置),最好在设计时考虑到从实际实现中抽象出来(保留在 .plist、数据库等中)。
所有这些单独的值都由一个概念组合在一起,因此可以由项目中的一个类来表示。这个类“总结”了与概念相关的实现细节。此逻辑与程序的其他部分隔离,当您需要更改它时,您的更改仅限于单个实体,因此每次更改都不太可能破坏您的其余代码。
这个类可以这样实现:
/////////////
// 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];
}
差不多了。
当您想向 TextSettings 添加新字段时,您必须 (1) 将它们声明为 @properties,(2) 向 -isEqual: 和 -hash 实现添加检查,以及 (3) 向-encodeWithCoder 和 -initWithCoder。
太多了!你可能会说,但我会说不——这并不是矫枉过正。绝对比在NSUserDefaults 中搜索和比较单个值更好。
UPD:
将其用作普通设置:
// 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"];
}