MSStringifyMacros 提供了一种便捷的方法来编写通常繁琐且可能存在错误的 NSUserDefaults
和 NSCoding
代码。
以下是一个关于 NSUserDefaults
的示例。通常,当为 NSUserDefaults
编码时,你会遵循以下方法,你需要为键创建常量,然后设置和获取默认值。
// constants for keys...
static NSString const * kKeyForFoo = @"keyForFoo";
static NSString const * kKeyForBar = @"keyForBar";
// setting defaults...
[[NSUserDefaults standardUserDefaults] setObject:self.foo forKey:kKeyForFoo];
[[NSUserDefaults standardUserDefaults] setObject:self.bar forKey:kKeyForBar];
// getting defaults...
self.foo = [[NSUserDefaults standardUserDefaults] objectForKey:kKeyForFoo];
self.bar = [[NSUserDefaults standardUserDefaults] objectForKey:kKeyForBar];
通过利用预处理器功能(在下一节中解释)称为字符串化,上述繁琐的代码可以被替换为...
// setting defaults...
MSSetDefaultForObject(self.foo);
MSSetDefaultForObject(self.bar);
// getting defaults...
MSDefaultForObject(self.foo);
MSDefaultForObject(self.bar);
如您所见,代码量少了很多,它更简单,更不容易出错。如果你对它的工作方式感到好奇,可以跳转到字符串化部分。简而言之,所需键是根据你传递的属性、实例变量或局部变量的名称为你创建的。
您几乎可以在任何 Mac OS X 或 iOS 项目中安装 MSStringifyMacros。我不确定是否有过任何 Xcode 版本,其预处理器不支持将字符串化映射到 NSString
(请参阅下方的字符串化部分)。如果你知道,请告诉我。
或者您可以将所需的源文件添加到您的项目中:
宏用于方便地与 NSUserDefaults
和 NSCoding
一起工作。
宏支持所有常用的 NSUserDefaults
方法,方便地设置和获取默认值。
重要:您传递的参数可以是属性、实例变量或局部变量。请记住,您传递的参数的名称用于生成用于键的字符串(请参阅字符串化部分)。因此,一旦设置了默认值(或编码)后,您必须使用相同或具有相同名称的属性、实例变量或局部变量来获取默认值或解码。
// BOOL...
MSSetDefaultForBool(BOOL);
MSDefaultForBool(BOOL);
// double...
MSSetDefaultForDouble(double);
MSDefaultForDouble(double);
// float...
MSSetDefaultForFloat(float);
MSDefaultForFloat(float);
// integer...
MSSetDefaultForInteger(integer);
MSDefaultForInteger(integer);
// object...
MSSetDefaultForObject(object);
MSDefaultForObject(object);
MSRemoveDefaultForObject(object);
// array...
MSDefaultForArray(array);
// data...
MSDefaultForData(data);
// dictionary...
MSDefaultForDictionary(dictionary);
// string...
MSDefaultForString(string);
// array of strings...
MSDefaultForStringArray(arrayOfStrings);
// url...
MSDefaultForURL(url);
默认情况下,即使您为可变对象设置了默认值,NSUserDefaults
也返回不可变对象。这些宏方便地管理可变对象...
MSDefaultForMutableArray(mutableArray);
MSDefaultForMutableData(mutableData);
MSDefaultForMutableDictionary(mutableDictionary);
MSDefaultForMutableString(mutableString);
MSDefaultForStringArrayMutable(stringArrayMutable);
您还可以测试对象是否有默认值...
BOOL exists = MSDefaultExistsForObject(object);
BOOL doesNotExist = MSDefaultDoesNotExistForObject(object);
《NSCoding》宏分为两组。第一组用于归档和解档,第二组用于编码和解码。
这些宏提供了对《NSKeyedArchiver》的archiveRootObject:toFile:
和《NSKeyedUnarchiver》的unarchiveObjectWithFile:
的便捷快捷方法。
类似于《NSUserDefaults》宏,这些宏将您传递的对象字符串化,并将结果字符串用作文件名。文件写入并从Documents目录读取。
// archiving...
BOOL result;
MSArchiveToDocsDirectory(object, result);
if (result == NO) { };
// unarchiving...
MSUnarchiveFromDocsDirectory(object);
if (object == nil { };
这两个宏功能相同,但允许您指定文件名。
// archiving...
BOOL result;
MSArchiveToDocsDirectoryUsingFilename(object, result, filename);
if (result == NO) { };
MSUnarchiveFromDocsDirectoryUsingFilename(object, filename);
if (object == nil { };
这些宏支持所有常用的《NSKeyedArchiver》和《NSKeyedUnarchiver》方法,方便编码和解码。
// BOOL...
MSEncodeBool(BOOL);
MSDecodeBool(BOOL);
// double...
MSEncodeDouble(double);
MSDecodeDouble(double);
// float...
MSEncodeFloat(float);
MSDecodeFloat(float);
// int...
MSEncodeInt(int);
MSDecodeInt(int);
// int32...
MSEncodeInt32(int32_t);
MSDecodeInt32(int32_t);
// int64...
MSEncodeInt64(int64_t);
MSDecodeInt64(int64_t);
// objects...
MSEncodeObject(object);
MSDecodeObject(object);
// checking for a value...
MSContainsValue(value);
重要:这些宏假定您的编码器和解码器使用Xcode代码自动完成的标准化名称:分别为aCoder
和aDecoder
。换句话说,您的方法签名对于《NSCoding》的初始化和编码方法需要如下所示
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (instancetype)initWithCoder:(NSCoder *)aDecoder;
Xcode项目中包含了一系列完整的测试套件,因此您可以放心地使用这些宏。
如果您将测试文件复制到项目中,您可能需要配置项目以使测试目标能识别这些文件。
此代码根据MIT许可协议的条款和条件分发。
这些宏是由C预处理器的一个特性实现的,称为字符串化。基本上,字符串化将给定的符号作为一个C字符串返回。
当使用带有前置字符“#”的宏参数时,预处理器将其替换成实际参数的文本,并将其转换为字符串常量。
例如,使用这个宏...
#define Stringify(x) #x
此代码
Stringify(foo);
被预处理器替换为以'foo'为C字符串。但这更好。通过使用前缀@,您可以获得一个NSString
对象,而不是C字符串。这有多方便?因此,给定这些宏...
#define MSStringify(symbol) @#symbol
define MSSetDefaultForBool(BOOL) [[NSUserDefaults standardUserDefaults] setBool:BOOL forKey:MSStringify(BOOL)]
此代码...
MSSetDefaultForBool(self.yourSwitch.on);
在经过预处理器处理后成为...
[[NSUserDefaults standardUserDefaults] setBool:self.yourSwitch.on forKey:@"self.yourSwitch.on"];
您可以通过检查Xcode中预处理器输出自行查看结果。
对于《NSUserDefaults》和《NSCoding》,这些宏使得事情变得更容易,因为通过字符串化,所需的关键参数变成了自生成的。