NSObject+RACLifting.m 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //
  2. // NSObject+RACLifting.m
  3. // ReactiveObjC
  4. //
  5. // Created by Josh Abernathy on 10/13/12.
  6. // Copyright (c) 2012 GitHub, Inc. All rights reserved.
  7. //
  8. #import "NSObject+RACLifting.h"
  9. #import <ReactiveObjC/RACEXTScope.h>
  10. #import "NSInvocation+RACTypeParsing.h"
  11. #import "NSObject+RACDeallocating.h"
  12. #import "NSObject+RACDescription.h"
  13. #import "RACSignal+Operations.h"
  14. #import "RACTuple.h"
  15. @implementation NSObject (RACLifting)
  16. - (RACSignal *)rac_liftSelector:(SEL)selector withSignalOfArguments:(RACSignal *)arguments {
  17. NSCParameterAssert(selector != NULL);
  18. NSCParameterAssert(arguments != nil);
  19. @unsafeify(self);
  20. NSMethodSignature *methodSignature = [self methodSignatureForSelector:selector];
  21. NSCAssert(methodSignature != nil, @"%@ does not respond to %@", self, NSStringFromSelector(selector));
  22. return [[[[arguments
  23. takeUntil:self.rac_willDeallocSignal]
  24. map:^(RACTuple *arguments) {
  25. @strongify(self);
  26. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
  27. invocation.selector = selector;
  28. invocation.rac_argumentsTuple = arguments;
  29. [invocation invokeWithTarget:self];
  30. return invocation.rac_returnValue;
  31. }]
  32. replayLast]
  33. setNameWithFormat:@"%@ -rac_liftSelector: %s withSignalsOfArguments: %@", RACDescription(self), sel_getName(selector), arguments];
  34. }
  35. - (RACSignal *)rac_liftSelector:(SEL)selector withSignalsFromArray:(NSArray *)signals {
  36. NSCParameterAssert(signals != nil);
  37. NSCParameterAssert(signals.count > 0);
  38. NSMethodSignature *methodSignature = [self methodSignatureForSelector:selector];
  39. NSCAssert(methodSignature != nil, @"%@ does not respond to %@", self, NSStringFromSelector(selector));
  40. NSUInteger numberOfArguments __attribute__((unused)) = methodSignature.numberOfArguments - 2;
  41. NSCAssert(numberOfArguments == signals.count, @"Wrong number of signals for %@ (expected %lu, got %lu)", NSStringFromSelector(selector), (unsigned long)numberOfArguments, (unsigned long)signals.count);
  42. return [[self
  43. rac_liftSelector:selector withSignalOfArguments:[RACSignal combineLatest:signals]]
  44. setNameWithFormat:@"%@ -rac_liftSelector: %s withSignalsFromArray: %@", RACDescription(self), sel_getName(selector), signals];
  45. }
  46. - (RACSignal *)rac_liftSelector:(SEL)selector withSignals:(RACSignal *)firstSignal, ... {
  47. NSCParameterAssert(firstSignal != nil);
  48. NSMutableArray *signals = [NSMutableArray array];
  49. va_list args;
  50. va_start(args, firstSignal);
  51. for (id currentSignal = firstSignal; currentSignal != nil; currentSignal = va_arg(args, id)) {
  52. NSCAssert([currentSignal isKindOfClass:RACSignal.class], @"Argument %@ is not a RACSignal", currentSignal);
  53. [signals addObject:currentSignal];
  54. }
  55. va_end(args);
  56. return [[self
  57. rac_liftSelector:selector withSignalsFromArray:signals]
  58. setNameWithFormat:@"%@ -rac_liftSelector: %s withSignals: %@", RACDescription(self), sel_getName(selector), signals];
  59. }
  60. @end