mirror of
https://github.com/zhigang1992/GVUserDefaults.git
synced 2026-01-12 22:47:46 +08:00
@@ -1,3 +1,7 @@
|
||||
0.9.0 - January 28, 2013
|
||||
- Support primitive types (int, float, bool, double)
|
||||
- Improved performance due to accessor creation on start up
|
||||
|
||||
0.4.1 - January 7, 2013
|
||||
- Fix endless loop if no transformKey: method was present
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
// Removing it for debugging, starting with a clean slate every time
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultUserName"];
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultUserId"];
|
||||
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
|
||||
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
@@ -14,32 +14,37 @@
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultUserName"];
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultUserId"];
|
||||
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
|
||||
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultUserName"];
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultUserId"];
|
||||
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
|
||||
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testDefaults {
|
||||
STAssertEqualObjects([GVUserDefaults standardUserDefaults].userName, @"default", nil);
|
||||
STAssertEqualObjects([GVUserDefaults standardUserDefaults].userId, @1, nil);
|
||||
STAssertEquals([GVUserDefaults standardUserDefaults].integerValue, 123, nil);
|
||||
STAssertEquals([GVUserDefaults standardUserDefaults].boolValue, YES, nil);
|
||||
}
|
||||
|
||||
- (void)testSetters {
|
||||
[GVUserDefaults standardUserDefaults].userName = @"changed";
|
||||
[GVUserDefaults standardUserDefaults].userId = @2;
|
||||
[GVUserDefaults standardUserDefaults].integerValue = 456;
|
||||
|
||||
STAssertEqualObjects([GVUserDefaults standardUserDefaults].userName, @"changed", nil);
|
||||
STAssertEqualObjects([GVUserDefaults standardUserDefaults].userId, @2, nil);
|
||||
STAssertEquals([GVUserDefaults standardUserDefaults].integerValue, 456, nil);
|
||||
}
|
||||
|
||||
- (void)testGetters {
|
||||
STAssertEqualObjects([GVUserDefaults standardUserDefaults].userName, [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserName"], nil);
|
||||
STAssertEqualObjects([GVUserDefaults standardUserDefaults].userId, [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserId"], nil);
|
||||
STAssertEquals([GVUserDefaults standardUserDefaults].integerValue, [[NSUserDefaults standardUserDefaults] integerForKey:@"NSUserDefaultIntegerValue"], nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,5 +12,8 @@
|
||||
|
||||
@property (nonatomic, weak) NSString *userName;
|
||||
@property (nonatomic, weak) NSNumber *userId;
|
||||
@property (nonatomic) NSInteger integerValue;
|
||||
@property (nonatomic) BOOL boolValue;
|
||||
@property (nonatomic) float floatValue;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,10 +10,19 @@
|
||||
|
||||
@implementation GVUserDefaults (Properties)
|
||||
|
||||
@dynamic userName;
|
||||
@dynamic userId;
|
||||
@dynamic integerValue;
|
||||
@dynamic boolValue;
|
||||
@dynamic floatValue;
|
||||
|
||||
- (NSDictionary *)setupDefaults {
|
||||
return @{
|
||||
@"userName": @"default",
|
||||
@"userId": @1
|
||||
@"userId": @1,
|
||||
@"integerValue": @123,
|
||||
@"boolValue": @YES,
|
||||
@"floatValue": @12.3,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +31,4 @@
|
||||
return [NSString stringWithFormat:@"NSUserDefault%@", key];
|
||||
}
|
||||
|
||||
@dynamic userName;
|
||||
@dynamic userId;
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,28 +15,136 @@
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
NSString *test;
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
test = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserName"];
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
test = [GVUserDefaults standardUserDefaults].userName;
|
||||
NSLog(@"userName: %@", test);
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"Hello!" forKey:@"NSUSerDefaultUserName"];
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
[GVUserDefaults standardUserDefaults].userName = @"Hello!";
|
||||
|
||||
LogTimestamp;
|
||||
NSLog(@"Should be null:");
|
||||
NSLog(@"userName: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserName"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
NSLog(@"Should be default:");
|
||||
NSLog(@"userName: %@", [GVUserDefaults standardUserDefaults].userName);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"test1" forKey:@"NSUserDefaultUserName"];
|
||||
|
||||
NSLog(@"Should all be test1:");
|
||||
NSLog(@"userName: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserName"]);
|
||||
NSLog(@"userName: %@", [GVUserDefaults standardUserDefaults].userName);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[GVUserDefaults standardUserDefaults].userName = @"Test 2";
|
||||
|
||||
NSLog(@"Should all be test2:");
|
||||
NSLog(@"userName: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserName"]);
|
||||
NSLog(@"userName: %@", [GVUserDefaults standardUserDefaults].userName);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultUserName"];
|
||||
|
||||
NSLog(@"Should all be default:");
|
||||
NSLog(@"userName: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserName"]);
|
||||
NSLog(@"userName: %@", [GVUserDefaults standardUserDefaults].userName);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NSLog(@"Should all be 123:");
|
||||
NSLog(@"integerValue: %i", [GVUserDefaults standardUserDefaults].integerValue);
|
||||
NSLog(@"integerValue: %i", [[NSUserDefaults standardUserDefaults] integerForKey:@"NSUserDefaultIntegerValue"]);
|
||||
NSLog(@"integerValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultIntegerValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[GVUserDefaults standardUserDefaults].integerValue = 789;
|
||||
|
||||
NSLog(@"Should all be 789:");
|
||||
NSLog(@"integerValue: %i", [GVUserDefaults standardUserDefaults].integerValue);
|
||||
NSLog(@"integerValue: %i", [[NSUserDefaults standardUserDefaults] integerForKey:@"NSUserDefaultIntegerValue"]);
|
||||
NSLog(@"integerValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultIntegerValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultIntegerValue"];
|
||||
|
||||
NSLog(@"Should all be 123:");
|
||||
NSLog(@"integerValue: %i", [GVUserDefaults standardUserDefaults].integerValue);
|
||||
NSLog(@"integerValue: %i", [[NSUserDefaults standardUserDefaults] integerForKey:@"NSUserDefaultIntegerValue"]);
|
||||
NSLog(@"integerValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultIntegerValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NSLog(@"Should all be 1:");
|
||||
NSLog(@"boolValue: %i", [GVUserDefaults standardUserDefaults].boolValue);
|
||||
NSLog(@"boolValue: %i", [[NSUserDefaults standardUserDefaults] integerForKey:@"NSUserDefaultBoolValue"]);
|
||||
NSLog(@"boolValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultBoolValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[GVUserDefaults standardUserDefaults].boolValue = NO;
|
||||
|
||||
NSLog(@"Should all be 0:");
|
||||
NSLog(@"boolValue: %i", [GVUserDefaults standardUserDefaults].boolValue);
|
||||
NSLog(@"boolValue: %i", [[NSUserDefaults standardUserDefaults] integerForKey:@"NSUserDefaultBoolValue"]);
|
||||
NSLog(@"boolValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultBoolValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultBoolValue"];
|
||||
|
||||
NSLog(@"Should all be 1:");
|
||||
NSLog(@"boolValue: %i", [GVUserDefaults standardUserDefaults].boolValue);
|
||||
NSLog(@"boolValue: %i", [[NSUserDefaults standardUserDefaults] integerForKey:@"NSUserDefaultBoolValue"]);
|
||||
NSLog(@"boolValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultBoolValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NSLog(@"Should all be 12.3:");
|
||||
NSLog(@"floatValue: %f", [GVUserDefaults standardUserDefaults].floatValue);
|
||||
NSLog(@"floatValue: %f", [[NSUserDefaults standardUserDefaults] floatForKey:@"NSUserDefaultFloatValue"]);
|
||||
NSLog(@"floatValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultFloatValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[GVUserDefaults standardUserDefaults].floatValue = 66.6;
|
||||
|
||||
NSLog(@"Should all be 66.6:");
|
||||
NSLog(@"floatValue: %f", [GVUserDefaults standardUserDefaults].floatValue);
|
||||
NSLog(@"floatValue: %f", [[NSUserDefaults standardUserDefaults] floatForKey:@"NSUserDefaultFloatValue"]);
|
||||
NSLog(@"floatValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultFloatValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSUserDefaultFloatValue"];
|
||||
|
||||
NSLog(@"Should all be 12.3:");
|
||||
NSLog(@"floatValue: %f", [GVUserDefaults standardUserDefaults].floatValue);
|
||||
NSLog(@"floatValue: %f", [[NSUserDefaults standardUserDefaults] floatForKey:@"NSUserDefaultFloatValue"]);
|
||||
NSLog(@"floatValue OBJECT: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultFloatValue"]);
|
||||
NSLog(@"--------------------");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
NSString *value;
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
value = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaultUserName"];
|
||||
}
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
value = [GVUserDefaults standardUserDefaults].userName;
|
||||
}
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"Test 3" forKey:@"NSUserDefaultUserName"];
|
||||
}
|
||||
|
||||
LogTimestamp;
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
[GVUserDefaults standardUserDefaults].userName = @"Test 3";
|
||||
}
|
||||
|
||||
LogTimestamp;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "GVUserDefaults"
|
||||
s.version = "0.4.1"
|
||||
s.version = "0.9.0"
|
||||
s.summary = "NSUserDefaults access via properties."
|
||||
s.homepage = "https://github.com/gangverk/GVUserDefaults"
|
||||
s.license = 'MIT'
|
||||
|
||||
@@ -9,8 +9,104 @@
|
||||
#import "GVUserDefaults.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@interface GVUserDefaults ()
|
||||
@property (strong, nonatomic) NSMutableDictionary *mapping;
|
||||
@end
|
||||
|
||||
@implementation GVUserDefaults
|
||||
|
||||
enum TypeEncodings {
|
||||
Char = 'c',
|
||||
Short = 's',
|
||||
Int = 'i',
|
||||
Long = 'l',
|
||||
LongLong = 'q',
|
||||
UnsignedChar = 'C',
|
||||
UnsignedShort = 'S',
|
||||
UnsignedInt = 'I',
|
||||
UnsignedLong = 'L',
|
||||
UnsignedLongLong = 'Q',
|
||||
Float = 'f',
|
||||
Double = 'd',
|
||||
Object = '@'
|
||||
};
|
||||
|
||||
- (NSString *)defaultsKeyForPropertyNamed:(char const *)propertyName {
|
||||
NSString *key = [NSString stringWithFormat:@"%s", propertyName];
|
||||
return [self _transformKey:key];
|
||||
}
|
||||
|
||||
- (NSString *)defaultsKeyForSelector:(SEL)selector {
|
||||
return [self.mapping objectForKey:NSStringFromSelector(selector)];
|
||||
}
|
||||
|
||||
static long long longLongGetter(GVUserDefaults *self, SEL _cmd) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
return [[[NSUserDefaults standardUserDefaults] objectForKey:key] longLongValue];
|
||||
}
|
||||
|
||||
static void longLongSetter(GVUserDefaults *self, SEL _cmd, long long value) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
NSNumber *object = [NSNumber numberWithLongLong:value];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
|
||||
}
|
||||
|
||||
static bool boolGetter(GVUserDefaults *self, SEL _cmd) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
return [[NSUserDefaults standardUserDefaults] boolForKey:key];
|
||||
}
|
||||
|
||||
static void boolSetter(GVUserDefaults *self, SEL _cmd, bool value) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
[[NSUserDefaults standardUserDefaults] setBool:value forKey:key];
|
||||
}
|
||||
|
||||
static int integerGetter(GVUserDefaults *self, SEL _cmd) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
return [[NSUserDefaults standardUserDefaults] integerForKey:key];
|
||||
}
|
||||
|
||||
static void integerSetter(GVUserDefaults *self, SEL _cmd, int value) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:value forKey:key];
|
||||
}
|
||||
|
||||
static float floatGetter(GVUserDefaults *self, SEL _cmd) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
return [[NSUserDefaults standardUserDefaults] floatForKey:key];
|
||||
}
|
||||
|
||||
static void floatSetter(GVUserDefaults *self, SEL _cmd, float value) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
[[NSUserDefaults standardUserDefaults] setFloat:value forKey:key];
|
||||
}
|
||||
|
||||
static double doubleGetter(GVUserDefaults *self, SEL _cmd) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
return [[NSUserDefaults standardUserDefaults] doubleForKey:key];
|
||||
}
|
||||
|
||||
static void doubleSetter(GVUserDefaults *self, SEL _cmd, double value) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
[[NSUserDefaults standardUserDefaults] setDouble:value forKey:key];
|
||||
}
|
||||
|
||||
static id objectGetter(GVUserDefaults *self, SEL _cmd) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
return [[NSUserDefaults standardUserDefaults] objectForKey:key];
|
||||
}
|
||||
|
||||
static void objectSetter(GVUserDefaults *self, SEL _cmd, id object) {
|
||||
NSString *key = [self defaultsKeyForSelector:_cmd];
|
||||
if (object) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
|
||||
} else {
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Begin
|
||||
|
||||
+ (GVUserDefaults *)standardUserDefaults {
|
||||
static dispatch_once_t pred;
|
||||
static GVUserDefaults *sharedInstance = nil;
|
||||
@@ -31,27 +127,12 @@
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:mutableDefaults];
|
||||
}
|
||||
|
||||
[self generateAccessorMethods];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
|
||||
NSString *method = NSStringFromSelector(aSEL);
|
||||
|
||||
if ([method isEqualToString:@"transformKey:"] || [method isEqualToString:@"setupDefaults"]) {
|
||||
// Prevent endless loop for optional (and missing) category methods
|
||||
return [super resolveInstanceMethod:aSEL];
|
||||
}
|
||||
|
||||
if ([method hasPrefix:@"set"]) {
|
||||
class_addMethod([self class], aSEL, (IMP) accessorSetter, "v@:@");
|
||||
return YES;
|
||||
} else {
|
||||
class_addMethod([self class], aSEL, (IMP) accessorGetter, "@@:");
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)_transformKey:(NSString *)key {
|
||||
if ([self respondsToSelector:@selector(transformKey:)]) {
|
||||
return [self performSelector:@selector(transformKey:) withObject:key];
|
||||
@@ -60,20 +141,98 @@
|
||||
return key;
|
||||
}
|
||||
|
||||
id accessorGetter(GVUserDefaults *self, SEL _cmd) {
|
||||
NSString *key = NSStringFromSelector(_cmd);
|
||||
key = [self _transformKey:key];
|
||||
return [[NSUserDefaults standardUserDefaults] objectForKey:key];
|
||||
}
|
||||
- (void)generateAccessorMethods {
|
||||
unsigned int count = 0;
|
||||
objc_property_t *properties = class_copyPropertyList([self class], &count);
|
||||
|
||||
void accessorSetter(GVUserDefaults *self, SEL _cmd, id newValue) {
|
||||
NSString *method = NSStringFromSelector(_cmd);
|
||||
NSString *key = [[method stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""] stringByReplacingOccurrencesOfString:@":" withString:@""];
|
||||
key = [key stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[key substringToIndex:1] lowercaseString]];
|
||||
key = [self _transformKey:key];
|
||||
self.mapping = [NSMutableDictionary dictionary];
|
||||
|
||||
// Set value of the key anID to newValue
|
||||
[[NSUserDefaults standardUserDefaults] setObject:newValue forKey:key];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
objc_property_t property = properties[i];
|
||||
const char *name = property_getName(property);
|
||||
const char *attributes = property_getAttributes(property);
|
||||
|
||||
char *getter = strstr(attributes, ",G");
|
||||
if (getter) {
|
||||
getter = strdup(getter + 2);
|
||||
getter = strsep(&getter, ",");
|
||||
} else {
|
||||
getter = strdup(name);
|
||||
}
|
||||
SEL getterSel = sel_registerName(getter);
|
||||
free(getter);
|
||||
|
||||
char *setter = strstr(attributes, ",S");
|
||||
if (setter) {
|
||||
setter = strdup(setter + 2);
|
||||
setter = strsep(&setter, ",");
|
||||
} else {
|
||||
asprintf(&setter, "set%c%s:", toupper(name[0]), name + 1);
|
||||
}
|
||||
SEL setterSel = sel_registerName(setter);
|
||||
free(setter);
|
||||
|
||||
NSString *key = [self defaultsKeyForPropertyNamed:name];
|
||||
[self.mapping setValue:key forKey:NSStringFromSelector(getterSel)];
|
||||
[self.mapping setValue:key forKey:NSStringFromSelector(setterSel)];
|
||||
|
||||
IMP getterImp = NULL;
|
||||
IMP setterImp = NULL;
|
||||
char type = attributes[1];
|
||||
switch (type) {
|
||||
case Short:
|
||||
case Long:
|
||||
case LongLong:
|
||||
case UnsignedChar:
|
||||
case UnsignedShort:
|
||||
case UnsignedInt:
|
||||
case UnsignedLong:
|
||||
case UnsignedLongLong:
|
||||
getterImp = (IMP)longLongGetter;
|
||||
setterImp = (IMP)longLongSetter;
|
||||
break;
|
||||
|
||||
case Char:
|
||||
getterImp = (IMP)boolGetter;
|
||||
setterImp = (IMP)boolSetter;
|
||||
break;
|
||||
|
||||
case Int:
|
||||
getterImp = (IMP)integerGetter;
|
||||
setterImp = (IMP)integerSetter;
|
||||
break;
|
||||
|
||||
case Float:
|
||||
getterImp = (IMP)floatGetter;
|
||||
setterImp = (IMP)floatSetter;
|
||||
break;
|
||||
|
||||
case Double:
|
||||
getterImp = (IMP)doubleGetter;
|
||||
setterImp = (IMP)doubleSetter;
|
||||
break;
|
||||
|
||||
case Object:
|
||||
getterImp = (IMP)objectGetter;
|
||||
setterImp = (IMP)objectSetter;
|
||||
break;
|
||||
|
||||
default:
|
||||
free(properties);
|
||||
[NSException raise:NSInternalInconsistencyException format:@"Unsupported type of property \"%s\" in class %@", name, self];
|
||||
break;
|
||||
}
|
||||
|
||||
char types[5];
|
||||
|
||||
snprintf(types, 4, "%c@:", type);
|
||||
class_addMethod([self class], getterSel, getterImp, types);
|
||||
|
||||
snprintf(types, 5, "v@:%c", type);
|
||||
class_addMethod([self class], setterSel, setterImp, types);
|
||||
}
|
||||
|
||||
free(properties);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
21
README.md
21
README.md
@@ -9,12 +9,18 @@ Create a category on `GVUserDefaults`, add some properties in the .h file and ma
|
||||
@interface GVUserDefaults (Properties)
|
||||
@property (nonatomic, weak) NSString *userName;
|
||||
@property (nonatomic, weak) NSNumber *userId;
|
||||
@property (nonatomic) NSInteger integerValue;
|
||||
@property (nonatomic) BOOL boolValue;
|
||||
@property (nonatomic) float floatValue;
|
||||
@end
|
||||
|
||||
// .m
|
||||
@implementation GVUserDefaults (Properties)
|
||||
@dynamic userName;
|
||||
@dynamic userId;
|
||||
@dynamic integerValue;
|
||||
@dynamic boolValue;
|
||||
@dynamic floatValue;
|
||||
@end
|
||||
|
||||
Now, instead of using `[[NSUserDefaults standardUserDefaults] objectForKey:@"userName"]`, you can simply use `[GVUserDefaults standardUserDefaults].userName`.
|
||||
@@ -23,8 +29,6 @@ You can even save defaults by setting the property:
|
||||
|
||||
[GVUserDefaults standardUserDefaults].userName = @"myusername";
|
||||
|
||||
### Objects only
|
||||
At this moment only objects can be stored, so no integers or booleans. Just wrap them in an NSNumber.
|
||||
|
||||
### Key prefix
|
||||
The keys in NSUserDefaults are the same name as your properties. If you'd like to prefix or alter them, add a `transformKey:` method to your category. For example, to turn "userName" into "NSUserDefaultUserName":
|
||||
@@ -39,7 +43,8 @@ Registering defaults can be done as usual, on NSUserDefaults directly (use the s
|
||||
|
||||
NSDictionary *defaults = @{
|
||||
@"NSUserDefaultUserName": @"default",
|
||||
@"NSUserDefaultUserId": @1
|
||||
@"NSUserDefaultUserId": @1,
|
||||
@"NSUserDefaultBoolValue": @YES
|
||||
};
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
|
||||
@@ -49,14 +54,14 @@ However, it's a lot easier to create a setupDefaults method on the category, whi
|
||||
- (NSDictionary *)setupDefaults {
|
||||
return @{
|
||||
@"userName": @"default",
|
||||
@"userId": @1
|
||||
@"userId": @1,
|
||||
@"boolValue": @YES
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
### Performance
|
||||
The getter is about 3 times as slow as directly using NSUserDefaults, but we're talking about fractions of a millisecond (0.22 ms vs 0.65 ms on an iPod Touch 4th gen). The setter is about 3 times as slow as well (0.20 ms vs 0.61 ms).
|
||||
The numbers vary a bit from device to device and from run to run, but it always seems to be about 1.5 to 3 times as slow. For example on an iPhone 4 the setter takes 0.77 ms vs 0.5 ms when you do it natively.
|
||||
Performance is nearly identical to using NSUserDefaults directly. We're talking about a difference of 0.05 milliseconds or less.
|
||||
|
||||
|
||||
## Install
|
||||
@@ -78,3 +83,7 @@ GVUserDefaults is an open source project and your contribution is very much appr
|
||||
|
||||
## License
|
||||
GVUserDefaults is available under the MIT license. See the LICENSE file for more info.
|
||||
|
||||
|
||||
## Thanks
|
||||
A huge thank you goes to [ADVUserDefaults](https://github.com/advantis/ADVUserDefaults) for its method of creating accessors for primitive types.
|
||||
Reference in New Issue
Block a user