Last active
August 29, 2015 13:56
-
-
Save hartbit/9227494 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import "ATPInfo.h" | |
@interface ATPDecorator : NSObject <ATPInfo> | |
@property (nonatomic, strong, readonly) NSString* fullName; | |
- (id)initWithInfo:(NSObject<ATPInfo>*)info; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ATPDecorator.h" | |
@interface ATPDecorator () | |
@property (nonatomic, strong) NSObject<ATPInfo>* info; | |
@end | |
@implementation ATPDecorator | |
@dynamic firstName; | |
@dynamic lastName; | |
#pragma mark - Initialization | |
- (id)initWithInfo:(NSObject<ATPInfo>*)info | |
{ | |
if (self = [super init]) { | |
_info = info; | |
} | |
return self; | |
} | |
#pragma mark - Properties | |
+ (NSSet*)keyPathsForValuesAffectingFullName | |
{ | |
return [NSSet setWithObjects:@"info.firstName", @"info.lastName", nil]; | |
} | |
- (NSString*)fullName | |
{ | |
return [NSString stringWithFormat:@"%@ %@", self.info.firstName, self.info.lastName]; | |
} | |
#pragma mark - Forwarding Methods | |
- (id)forwardingTargetForSelector:(SEL)selector | |
{ | |
return [self.info respondsToSelector:selector] ? self.info : self; | |
} | |
- (BOOL)respondsToSelector:(SEL)selector | |
{ | |
return [super respondsToSelector:selector] || [self.info respondsToSelector:selector]; | |
} | |
- (BOOL)isKindOfClass:(Class)class | |
{ | |
return [super isKindOfClass:class] || [self.info isKindOfClass:class]; | |
} | |
- (void)addObserver:(NSObject*)observer forKeyPath:(NSString*)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context | |
{ | |
if ([self respondsToKeyPath:keyPath]) { | |
[super addObserver:observer forKeyPath:keyPath options:options context:context]; | |
} else { | |
[self.info addObserver:observer forKeyPath:keyPath options:options context:context]; | |
} | |
} | |
- (void)removeObserver:(NSObject*)observer forKeyPath:(NSString*)keyPath | |
{ | |
if ([self respondsToKeyPath:keyPath]) { | |
[super removeObserver:observer forKeyPath:keyPath]; | |
} else { | |
[self.info removeObserver:observer forKeyPath:keyPath]; | |
} | |
} | |
- (void)removeObserver:(NSObject*)observer forKeyPath:(NSString*)keyPath context:(void*)context | |
{ | |
if ([self respondsToKeyPath:keyPath]) { | |
[super removeObserver:observer forKeyPath:keyPath context:context]; | |
} else { | |
[self.info removeObserver:observer forKeyPath:keyPath context:context]; | |
} | |
} | |
- (BOOL)respondsToKeyPath:(NSString*)keyPath | |
{ | |
NSArray* keys = [keyPath componentsSeparatedByString:@"."]; | |
NSString* firstKey = keys[0]; | |
if (![super respondsToSelector:NSSelectorFromString(firstKey)]) { | |
return NO; | |
} | |
NSUInteger keyCount = [keys count]; | |
if (keyCount > 1) { | |
id currentObject = [self valueForKey:firstKey]; | |
for (NSUInteger index = 1; index < keyCount; index++) { | |
NSString* currentKey = keys[index]; | |
if (![currentObject respondsToSelector:NSSelectorFromString(currentKey)]) { | |
return NO; | |
} | |
currentObject = [currentObject valueForKey:currentKey]; | |
} | |
} | |
return YES; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@protocol ATPInfo <NSObject> | |
@property (nonatomic, strong) NSString* firstName; | |
@property (nonatomic, strong) NSString* lastName; | |
@end | |
@interface ATPInfo : NSObject <ATPInfo> | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ATPInfo.h" | |
@implementation ATPInfo | |
@synthesize firstName = _firstName; | |
@synthesize lastName = _lastName; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot update for observer <ATPAppDelegate 0x8a1f5f0> for the key path "fullName.length" from <ATPDecorator 0x8a53f70>, most likely because the value for the key "fullName" has changed without an appropriate KVO notification being sent. Check the KVO-compliance of the ATPDecorator class.' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ATPInfo* info = [ATPInfo new]; | |
info.firstName = @"David"; | |
info.lastName = @"Hart"; | |
ATPDecorator* decorator = [[ATPDecorator alloc] initWithInfo:info]; | |
[decorator addObserver:self forKeyPath:@"firstName" options:NSKeyValueObservingOptionNew context:kKVOContext]; | |
[decorator addObserver:self forKeyPath:@"firstName.length" options:NSKeyValueObservingOptionNew context:kKVOContext]; | |
[decorator addObserver:self forKeyPath:@"fullName" options:NSKeyValueObservingOptionNew context:kKVOContext]; | |
[decorator addObserver:self forKeyPath:@"fullName.length" options:NSKeyValueObservingOptionNew context:kKVOContext]; | |
info.firstName = @"Stephen"; | |
decorator.firstName = @"Charlotte"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment