Upgrade to Pro — share decks privately, control downloads, hide ads and more …

NSProxy, multithreading, messaging

NSProxy, multithreading, messaging

Cyril Lashkevich

March 13, 2014
Tweet

More Decks by Cyril Lashkevich

Other Decks in Programming

Transcript

  1. "All problems in computer science can be solved by another

    level of indirection..." David Wheeler wtorek, 10 września 13
  2. "All problems in computer science can be solved by another

    level of indirection..." David Wheeler "...except for the problem of too many layers of indirection." Kevlin Henney wtorek, 10 września 13
  3. Задача Прозрачно пересылать вызовы методов обекта (например делегата) в другой

    поток [obj performSelector:@selector(doThing:) onThread:thread withObject:param waitUntilDone:NO]; wtorek, 10 września 13
  4. Задача Прозрачно пересылать вызовы методов обекта (например делегата) в другой

    поток [obj performSelector:@selector(doThing:) onThread:thread withObject:param waitUntilDone:NO]; wtorek, 10 września 13
  5. Задача Прозрачно пересылать вызовы методов обекта (например делегата) в другой

    поток [obj performSelector:@selector(doThing:) onThread:thread withObject:param waitUntilDone:NO]; [obj doThing:param]; wtorek, 10 września 13
  6. NSProxy Абстрактный класс Реализует протокол NSObject Минимальная реализация требует переопределения

    2х методов - (void)forwardInvocation:(NSInvocation *) invocation - (NSMethodSignature *) methodSignatureForSelector:(SEL)aSelector // Всегда возвращает результат wtorek, 10 września 13
  7. Интерфейс @interface ThreadProxy : NSProxy @property (weak) id target; -

    (id)initWithTarget:(id)target thread:(NSThread *)thread @end wtorek, 10 września 13
  8. Приватная часть интерфейса @interface ThreadProxy () { @protected NSThread *_thread;

    id _target; Class _targetClass; } - (void)_invokeInvocation:(NSInvocation *)invocation; @end wtorek, 10 września 13
  9. init - (id)initWithTarget:(id)target thread:(NSThread *)thread { if (!thread) self =

    nil; if (self) { _thread = thread; _target = target; _targetClass = [target class]; } return self; } wtorek, 10 września 13
  10. - (NSMethodSignature *) methodSignatureForSelector: (SEL)aSelector { return [_targetClass instanceMethodSignatureForSelector: aSelector];

    } - (BOOL)respondsToSelector:(SEL)aSelector { return [self.target respondsToSelector:aSelector]; } wtorek, 10 września 13
  11. - (void)setTarget:(id)target { @synchronized(self) { _target = target; if (target)

    { _targetClass = [target class]; } } } - (id)target { @synchronized(self) { return _target; } } wtorek, 10 września 13
  12. NSInvocation Вызов метода "замороженный" в виде объекта target, selector и

    параметры могут быть изменены Вызов можно делать сколько угодно раз Не для vararg и union параметров wtorek, 10 września 13
  13. @implementation NSThread (ProxyAdditions) - (void)_invokeWithThreadProxy:(NSInvocation *)invocation { ThreadProxy *p =

    invocation.target; [p _invokeInvocation:invocation]; } @end - (void)forwardInvocation:(NSInvocation *)invocation { [invocation retainArguments]; } wtorek, 10 września 13
  14. @implementation NSThread (ProxyAdditions) - (void)_invokeWithThreadProxy:(NSInvocation *)invocation { ThreadProxy *p =

    invocation.target; [p _invokeInvocation:invocation]; } @end - (void)forwardInvocation:(NSInvocation *)invocation { [invocation retainArguments]; [_thread performSelector: @selector(_invokeWithTreadProxy:) onThread:_thread withObject:invocation waitUntilDone:NO]; } wtorek, 10 września 13
  15. - (void)_invokeInvocation:(NSInvocation *)invocation { if (_target) { [invocation invokeWithTarget:_target]; }

    } - (void)_invokeInvocation:(NSInvocation *)invocation { if ([_target respondsToSelector: invocation.selector]) { [invocation invokeWithTarget:_target]; } } wtorek, 10 września 13
  16. - (void)forwardInvocation:(NSInvocation *)invocation { NSMethodSignature *s = invocation.methodSignature; NSInteger lastArg

    = s.numberOfArguments - 1; const void *block = nil; [invocation getArgument:&block atIndex:lastArg]; block = Block_copy(block); [invocation setArgument:&block atIndex:lastArg]; [invocation retainArguments]; Block_release(block); [_thread performSelector:@selector(_invokeWithTreadProxy:) onThread:_thread withObject:invocation waitUntilDone:NO]; } wtorek, 10 września 13