@interface SomeClass : NSObject <SomeClassInterface> @end @interface ChildClass : SomeClass -(void) additionalMethod; @end @interface DecoratorClass : NSObject <SomeClassInterface> ... ChildClass *instance = [ChildClass new]; id decoratedInstance = [DecoratorClass decoratedInstanceOf:instance]
@interface SomeClass : NSObject; -(int) getNumber; -(NSString*) getString; @end @interface SimpleDecorator : NSProxy @property (nonatomic, strong) SomeClass *instance; +(instancetype) decoratedInstanceOf:(SomeClass*)instance; @end @implementation SimpleDecorator -(instancetype) initWithObject:(SomeClass*)object { /* - NSProxy , NSObject. [super init] */ _instance = object; return self; } +(instancetype) decoratedInstanceOf:(SomeClass*)instance { return [[self alloc] initWithObject:instance]; } /* NSProxy - , , . , , - SomeClass */ - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [self.instance methodSignatureForSelector:selector]; } - (void)forwardInvocation:(NSInvocation *)invocation { /* , , , - , , , , getString */ [invocation invokeWithTarget:self.instance]; } /* . NSProxy - */ - (int) getNumber { return [self.instance getNumber] + 1; } @end
SomeClass *object = [SomeClass new]; object = (SomeClass*)[SimpleDecorator decoratedInstanceOf:object]; NSLog(@"%d", [object getNumber]); NSLog(@"%@", [object getString]);
/* , . */ @interface Popup : NSObject; /* , , */ @property (nonatomic, strong) NSString* key; @property (nonatomic, strong) NSString* message; /* , , UIAppearance */ +(DelayedActionsProxy*) delayedInitializerForKey:(NSString*)key; /* . , */ -(void) showPopup @end @implementation Popup -(void) showPopup { [DelayedActionsProxy invokeDelayedInvocationsWithTarget:self]; /*...*/ } +(DelayedActionsProxy*) delayedInitializerForKey:(NSString*)key { return [DelayedActionsProxy sharedProxyForKey:key fromClass:[self class]]; } @end
@interface DelayedActionsProxy : NSProxy +(void) invokeDelayedInvocationsWithTarget:(Popup*) target; +(instancetype) sharedProxyForKey:(NSString*)key fromClass:(Class)objectClass; @end @interface DelayedActionsProxy() /* , - */ @property (nonatomic, strong) NSString *currentKey; @property (nonatomic, assign) Class currentClass; @property (nonatomic, strong) NSMutableDictionary *delayedInvocations; @end @implementation DelayedActionsProxy -(instancetype) init { self.delayedInvocations = [NSMutableDictionary new]; return self; } static DelayedActionsProxy *proxy = nil; +(instancetype) sharedProxyForKey:(NSString*)key fromClass:(Class)objectClass { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ proxy = [[self alloc] init]; }); proxy.currentKey = key; proxy.currentClass = objectClass; return proxy; } /* [[Popup delayedInitializerForKey:@"key"] setText:@"someText"], - , currentKey currentClass */ - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { /* currentClass , , instanceMethodSignature methodSignature */ return [self.currentClass instanceMethodSignatureForSelector:selector]; } - (void)forwardInvocation:(NSInvocation *)invocation { if (!self.delayedInvocations[self.currentKey]) { self.delayedInvocations[self.currentKey] = [NSMutableArray new]; } /* , */ [self.delayedInvocations[self.currentKey] addObject:invocation]; } /* */ +(void) invokeDelayedInvocationsWithTarget:(Popup*) target { for (NSInvocation *invocation in proxy.delayedInvocations[proxy.currentKey]) { [invocation invokeWithTarget:target]; } [proxy.delayedInvocations removeObjectForKey:proxy.currentKey]; } @end
[[Popup delayedInitializerForKey:@"key"] setText:@"someText"];
@interface Entity : NSObject; @property (nonatomic, strong) CCNode* node; @end @implementation Entity -(void)setRepresentation:(CCNode *)node { /* - ... */ _node = (CCNode*)[MainThreadProxy node]; } @end
@interface MainThreadProxy : NSProxy +(instancetype) proxyWithObject:(id)object; /* , , */ -(void)performBlock:(void (^)(id object))block; @end @interface MainThreadProxy() @property (nonatomic, strong) id object; @end @implementation MainThreadProxy -(instancetype) initWithObject:(id)object { self.object = object; return self; } +(instancetype) proxyWithObject:(id)object { return [[self alloc] initWithObject:object]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [self.object methodSignatureForSelector:selector]; } - (void)forwardInvocation:(NSInvocation *)invocation { if ([NSThread isMainThread]) { [invocation invokeWithTarget:self.object]; } else { [invocation performSelectorOnMainThread:@selector(invokeWithTarget:) withObject:self.object waitUntilDone:YES]; } } -(void)performBlock:(void (^)(id object))block { if ([NSThread isMainThread]) { block(self.object); } else { dispatch_sync(dispatch_get_main_queue(), ^{block(self.object);}); } } @end
[entity.node render];
[[object makeCallWithTimeInterval:1.0f andRepeatCount:2] someMethod];
[entity.node.effect update];
Source: https://habr.com/ru/post/235041/
All Articles