NSObject+RACSelectorSignal.h 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //
  2. // NSObject+RACSelectorSignal.h
  3. // ReactiveObjC
  4. //
  5. // Created by Josh Abernathy on 3/18/13.
  6. // Copyright (c) 2013 GitHub, Inc. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. @class RACTuple;
  10. @class RACSignal<__covariant ValueType>;
  11. NS_ASSUME_NONNULL_BEGIN
  12. /// The domain for any errors originating from -rac_signalForSelector:.
  13. extern NSErrorDomain const RACSelectorSignalErrorDomain;
  14. typedef NS_ERROR_ENUM(RACSelectorSignalErrorDomain, RACSelectorSignalError) {
  15. /// -rac_signalForSelector: was going to add a new method implementation for
  16. /// `selector`, but another thread added an implementation before it was able to.
  17. ///
  18. /// This will _not_ occur for cases where a method implementation exists before
  19. /// -rac_signalForSelector: is invoked.
  20. RACSelectorSignalErrorMethodSwizzlingRace = 1,
  21. };
  22. @interface NSObject (RACSelectorSignal)
  23. /// Creates a signal associated with the receiver, which will send a tuple of the
  24. /// method's arguments each time the given selector is invoked.
  25. ///
  26. /// If the selector is already implemented on the receiver, the existing
  27. /// implementation will be invoked _before_ the signal fires.
  28. ///
  29. /// If the selector is not yet implemented on the receiver, the injected
  30. /// implementation will have a `void` return type and accept only object
  31. /// arguments. Invoking the added implementation with non-object values, or
  32. /// expecting a return value, will result in undefined behavior.
  33. ///
  34. /// This is useful for changing an event or delegate callback into a signal. For
  35. /// example, on an NSView:
  36. ///
  37. /// [[view rac_signalForSelector:@selector(mouseDown:)] subscribeNext:^(RACTuple *args) {
  38. /// NSEvent *event = args.first;
  39. /// NSLog(@"mouse button pressed: %@", event);
  40. /// }];
  41. ///
  42. /// selector - The selector for whose invocations are to be observed. If it
  43. /// doesn't exist, it will be implemented to accept object arguments
  44. /// and return void. This cannot have C arrays or unions as arguments
  45. /// or C arrays, unions, structs, complex or vector types as return
  46. /// type.
  47. ///
  48. /// Returns a signal which will send a tuple of arguments upon each invocation of
  49. /// the selector, then completes when the receiver is deallocated. `next` events
  50. /// will be sent synchronously from the thread that invoked the method. If
  51. /// a runtime call fails, the signal will send an error in the
  52. /// RACSelectorSignalErrorDomain.
  53. - (RACSignal<RACTuple *> *)rac_signalForSelector:(SEL)selector;
  54. /// Behaves like -rac_signalForSelector:, but if the selector is not yet
  55. /// implemented on the receiver, its method signature is looked up within
  56. /// `protocol`, and may accept non-object arguments.
  57. ///
  58. /// If the selector is not yet implemented and has a return value, the injected
  59. /// method will return all zero bits (equal to `nil`, `NULL`, 0, 0.0f, etc.).
  60. ///
  61. /// selector - The selector for whose invocations are to be observed. If it
  62. /// doesn't exist, it will be implemented using information from
  63. /// `protocol`, and may accept non-object arguments and return
  64. /// a value. This cannot have C arrays or unions as arguments or
  65. /// return type.
  66. /// protocol - The protocol in which `selector` is declared. This will be used
  67. /// for type information if the selector is not already implemented on
  68. /// the receiver. This must not be `NULL`, and `selector` must exist
  69. /// in this protocol.
  70. ///
  71. /// Returns a signal which will send a tuple of arguments on each invocation of
  72. /// the selector, or an error in RACSelectorSignalErrorDomain if a runtime
  73. /// call fails.
  74. - (RACSignal<RACTuple *> *)rac_signalForSelector:(SEL)selector fromProtocol:(Protocol *)protocol;
  75. @end
  76. NS_ASSUME_NONNULL_END