рдХреНрдпрд╛ рдЖрдкрдиреЗ рдХрднреА рдХрд┐рдЪреЗрди рдпрд╛ NSUserDefaults рдХреЗ рд▓рд┐рдП рдПрдбрд╛рдкреНрдЯрд░реНрд╕ рд▓рд┐рдЦреЗ рд╣реИрдВ? рд╡реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдПрдХ рд╣реА рдмрд╕рдиреЗ рд╡рд╛рд▓реЗ рдФрд░ рдкрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕реЗ рдмрдиреЗ рд╣реЛрддреЗ рд╣реИрдВред рдореИрдВ рддрд░реНрдХ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ, рдмрд╛рдХреА рдХреЛ рд░рдирдЯрд╛рдЗрдо рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП, рдореИрдВ рдмрд┐рд▓реНрд▓реА рдХреЗ рд▓рд┐рдП рдкреВрдЫрддрд╛ рд╣реВрдВред

рдирдорд╕реНрдХрд╛рд░ред рдЖрдк рдХреЗ рд╕рд╛рде рдлрд┐рд░ рд╕реЗ FunCorp рд╕реЗ vdugnistред рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдХрд┐рдЪреЗрди рдПрдбреЗрдкреНрдЯрд░ рдореЗрдВ рдПрдХ рдирдпрд╛ рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝рддреЗ рд╕рдордп, рдореИрдВрдиреЗ рдкрдбрд╝реЛрд╕реА рд╡рд┐рдзрд┐ рд╕реЗ рдХреЛрдб рдХреЙрдкреА рдХрд░рддреЗ рд╕рдордп рдПрдХ рддреНрд░реБрдЯрд┐ рдкрдХрдбрд╝реАред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд╣рд▓реЗ рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рдерд╛:
- (Credentials *)credentials { // implementation details } - (void)setCredentials:(Credentials *)credentials { // implementation details } - (NSDate *)firstLaunchDate { // implementation details } - (void)setFirstLaunchDate:(NSDate *)date { // implementation details }
рдХреЛрдб рдХреЛ рдХреЗрд╡рд▓ рдирд┐рдХрдЯрддрдо рд╡рд┐рдзрд┐ рд╕реЗ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЙрд╕рдореЗрдВ рд╕реНрдерд┐рд░рд╛рдВрдХ рдмрджрд▓ рдЧрдП рдереЗред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдЧрд▓рддреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдереЛрдбрд╝реЗ рд╕реЗ рд░реАрдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдХреЗ рдмрд╛рдж, рдпрд╣ рдХреНрд▓рд╛рд╕ рд▓реЙрдЬрд┐рдХ рдХреЗ рдкреВрд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЛ рддрд░реАрдХреЛрдВ рд╕реЗ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдХрд▓рд╛:
- (Credentials *)credentials { return [self objectFromKeychainForKey:@"credentials"]; } - (void)setCredentials:(Credentials *)credentials { [self setObject:credentials toKeychainForKey:@"credentials"]; } - (NSDate *)firstLaunchDate { return [self objectFromKeychainForKey:@"firstLaunchDate"]; } - (void)setFirstLaunchDate:(NSDate *)firstLaunchDate { [self setObject:firstLaunchDate toKeychainForKey:@"firstLaunchDate"]; } - (void)setObject:(id)obj toKeychainForKey:(NSString *)key {
рдкрд╣рд▓реЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИред рд▓реЗрдХрд┐рди рджреЛ рдФрд░ рд╕рдорд╕реНрдпрд╛рдПрдВ рдмрдиреА рд╣реБрдИ рд╣реИрдВ:
- рдЖрдкрдХреЛ рдЕрднреА рднреА рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрдерд┐рд░рд╛рдВрдХ рдореЗрдВ рд╕реАрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рд╡рд┐рдзрд┐ рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ;
- рдкреВрд░реЗ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рд╣реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рддрд░реАрдХреЗ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗ, рдЬреЛ рдХреЗрд╡рд▓ рддрдерд╛рдХрдерд┐рдд рд╡рд┐рдзрд┐ рдХреЗ рддрд░реНрдХ рдореЗрдВ рднрд┐рдиреНрди рд╣реЛрддреЗ рд╣реИрдВред
рдФрд░ рдпрд╣рд╛рдБ рд╣рдорд╛рд░реА рдорджрдж рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИред рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдореЗрдВ, рдЬрдм @property рдХреЛ рдХреНрд▓рд╛рд╕ рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕реЗрдЯрд░, рдЧреЗрдЯреНрдЯрд░ рдФрд░ рдЖрдЗрд╡рд░ рд╕реНрд╡рддрдГ рдЙрддреНрдкрдиреНрди рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдорд╛рдирдХ рд╕реЗрдЯрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдорд╛рди рдЖрдЗрд╡рд░ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЧреЗрдЯреНрдЯрд░ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдЖрдЗрд╡рд░ рд╕реЗ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдХреНрд╖рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЖрдкрдХреЛ рдЧрддрд┐рд╢реАрд▓ <рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдирд╛рдо> рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдлрд┐рд░, рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рд╣рдореЗрдВ рдПрдХ рдЕрдЬреНрдЮрд╛рдд рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдорд┐рд▓реЗрдЧрд╛, рдЬрд┐рд╕реЗ рдЕрдкрд╡рд╛рдж рдЕрдкрд╡рд╛рдж рдореЗрдВ рднреЗрдЬрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЕрдкрд╡рд╛рдж рднреЗрдЬрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╡рд░реНрдЧ +(BOOL)resolveInstanceMethod:(SEL)sel
рдХреЛ +(BOOL)resolveInstanceMethod:(SEL)sel
рдХрд░реЗрдЧрд╛ +(BOOL)resolveInstanceMethod:(SEL)sel
рд╡рд┐рдзрд┐ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рдВрдкрддреНрддрд┐ рдпрд╛ +(BOOL)resolveClassMethod:(SEL)sel
рд╡рд░реНрдЧ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВред
рдЙрди рдореЗрдВ, рдЖрдк class_addMethod
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЪрдпрдирдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдзрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдпрджрд┐ рд╕рдм рдХреБрдЫ рд╕реБрдЪрд╛рд░реВ рд░реВрдк рд╕реЗ рдЪрд▓рд╛ рдЧрдпрд╛ рд╣реИ рддреЛ YES
рд▓реМрдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╡рд░реНрддрдорд╛рди рдФрд░ рдмрд╛рдж рдХреЗ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдирдП рдЬреЛрдбрд╝реЗ рдЧрдП рддрд░реАрдХреЗ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЙрд╕ рдХрдХреНрд╖рд╛ рдореЗрдВ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬрд┐рд╕рдореЗрдВ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реА рдЬрд╛рдПрдЧреА, рдПрдХ рдЪрдпрдирдХрд░реНрддрд╛, рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмреНрд▓реЙрдХ рдФрд░ рдПрдХ рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ред рдЕрдВрддрд┐рдо рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред
рдореИрдВрдиреЗ рддреБрд░рдВрдд рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдХрдХреНрд╖рд╛ рдХреА рд╕рдВрдкрддреНрддрд┐ рдФрд░ рдЙрджрд╛рд╣рд░рдг рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдЙрджрд╛рд╣рд░рдг рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред
+ (BOOL)resolveClassMethod:(SEL)sel { return [self resolveMethodFor:object_getClass(self) selector:sel]; } + (BOOL)resolveInstanceMethod:(SEL)sel { return [self resolveMethodFor:self selector:sel]; } + (BOOL)resolveMethodFor:(id)target selector:(SEL)sel { if (!sel_isGetterOrSetter(target, sel)) { return NO; } objc_property_t property = propertyForSelector(target, sel); if (sel_isSetter(target, sel)) { SEL getterSel = sel_getterFromSetter(sel); dvPropertySetterBlock setterBlock = [self setterBlockForTarget:target getterSelector:getterSel]; IMP blockImplementation = imp_implementationWithBlock(setterBlock); char *methodTypes = copySetterMethodTypesForProperty(property); assert(class_addMethod(target, sel, blockImplementation, methodTypes)); free(methodTypes); } else { dvPropertyGetterBlock getterBlock = [self getterBlockForTarget:target getterSelector:sel]; IMP blockImplementation = imp_implementationWithBlock(getterBlock); char *methodTypes = copyGetterMethodTypesForProperty(property); assert(class_addMethod(target, sel, blockImplementation, methodTypes)); free(methodTypes); } return YES; } + (dvPropertySetterBlock)setterBlockForTarget:(id)target getterSelector:(SEL)getterSelector { @throw @"Override this method in subclass"; } + (dvPropertyGetterBlock)getterBlockForTarget:(id)target getterSelector:(SEL)getterSelector { @throw @"Override this method in subclass"; }
рд╡рд╛рд░рд┐рд╕реЛрдВ рдореЗрдВ, рдпрд╣ рджреЛ рддрд░реАрдХреЛрдВ (рдЧреЗрдЯреНрдЯрд░ рдмреНрд▓реЙрдХ рдФрд░ рд╕реЗрдЯрд░ рдмреНрд▓реЙрдХ) рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ @property рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╢реАрд▓ рдЬреЛрдбрд╝реЗрдВред рдпрд╣рд╛рдБ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, NSUserDefaults рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдбрд╛рдкреНрдЯрд░ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ:
+ (dvPropertySetterBlock)setterBlockForTarget:(id)target getterSelector:(SEL)getterSelector { return ^(id blockSelf, id value) { [[NSUserDefaults standardUserDefaults] setObject:value forKey:NSStringFromSelector(getterSelector)]; }; } + (dvPropertyGetterBlock)getterBlockForTarget:(id)target getterSelector:(SEL)getterSelector { return ^id(id blockSelf) { return [[NSUserDefaults standardUserDefaults] objectForKey:NSStringFromSelector(getterSelector)]; }; }
рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЦреБрдж рдЧрд┐рдареБрдм рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдореИрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЖрдкрдХреЗ рд╕рд╡рд╛рд▓реЛрдВ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реВрдВред