A2DynamicDelegate.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //
  2. // A2DynamicDelegate.h
  3. // BlocksKit
  4. //
  5. #import <Foundation/Foundation.h>
  6. #import "NSObject+A2BlockDelegate.h"
  7. #import "NSObject+A2DynamicDelegate.h"
  8. /** A2DynamicDelegate implements a class's delegate, data source, or other
  9. delegated protocol by associating protocol methods with a block implementation.
  10. - (IBAction) annoyUser
  11. {
  12. // Create an alert view
  13. UIAlertView *alertView = [[UIAlertView alloc]
  14. initWithTitle:@"Hello World!"
  15. message:@"This alert's delegate is implemented using blocks. That's so cool!"
  16. delegate:nil
  17. cancelButtonTitle:@"Meh."
  18. otherButtonTitles:@"Woo!", nil];
  19. // Get the dynamic delegate
  20. A2DynamicDelegate *dd = alertView.bk_dynamicDelegate;
  21. // Implement -alertViewShouldEnableFirstOtherButton:
  22. [dd implementMethod:@selector(alertViewShouldEnableFirstOtherButton:) withBlock:^(UIAlertView *alertView) {
  23. NSLog(@"Message: %@", alertView.message);
  24. return YES;
  25. }];
  26. // Implement -alertView:willDismissWithButtonIndex:
  27. [dd implementMethod:@selector(alertView:willDismissWithButtonIndex:) withBlock:^(UIAlertView *alertView, NSInteger buttonIndex) {
  28. NSLog(@"You pushed button #%d (%@)", buttonIndex, [alertView buttonTitleAtIndex:buttonIndex]);
  29. }];
  30. // Set the delegate
  31. alertView.delegate = dd;
  32. [alertView show];
  33. }
  34. A2DynamicDelegate is designed to be 'plug and play'.
  35. */
  36. @interface A2DynamicDelegate : NSProxy
  37. /**
  38. * The designated initializer for the A2DynamicDelegate proxy.
  39. *
  40. * An instance of A2DynamicDelegate should generally not be created by the user,
  41. * but instead by calling a method in NSObject(A2DynamicDelegate). Since
  42. * delegates are usually weak references on the part of the delegating object, a
  43. * dynamic delegate would be deallocated immediately after its declaring scope
  44. * ends. NSObject(A2DynamicDelegate) creates a strong reference.
  45. *
  46. * @param protocol A protocol to which the dynamic delegate should conform.
  47. * @return An initialized delegate proxy.
  48. */
  49. - (id)initWithProtocol:(Protocol *)protocol;
  50. /** The protocol delegating the dynamic delegate. */
  51. @property (nonatomic, readonly) Protocol *protocol;
  52. /** A dictionary of custom handlers to be used by custom responders
  53. in a A2Dynamic(Protocol Name) subclass of A2DynamicDelegate, like
  54. `A2DynamicUIAlertViewDelegate`. */
  55. @property (nonatomic, strong, readonly) NSMutableDictionary *handlers;
  56. /** When replacing the delegate using the A2BlockDelegate extensions, the object
  57. responding to classical delegate method implementations. */
  58. @property (nonatomic, weak, readonly) id realDelegate;
  59. /** @name Block Instance Method Implementations */
  60. /** The block that is to be fired when the specified
  61. selector is called on the reciever.
  62. @param selector An encoded selector. Must not be NULL.
  63. @return A code block, or nil if no block is assigned.
  64. */
  65. - (id)blockImplementationForMethod:(SEL)selector;
  66. /** Assigns the given block to be fired when the specified
  67. selector is called on the reciever.
  68. [tableView.dynamicDataSource implementMethod:@selector(numberOfSectionsInTableView:)
  69. withBlock:NSInteger^(UITableView *tableView) {
  70. return 2;
  71. }];
  72. @warning Starting with A2DynamicDelegate 2.0, a block will
  73. not be checked for a matching signature. A block can have
  74. less parameters than the original selector and will be
  75. ignored, but cannot have more.
  76. @param selector An encoded selector. Must not be NULL.
  77. @param block A code block with the same signature as selector.
  78. */
  79. - (void)implementMethod:(SEL)selector withBlock:(id)block;
  80. /** Disassociates any block so that nothing will be fired
  81. when the specified selector is called on the reciever.
  82. @param selector An encoded selector. Must not be NULL.
  83. */
  84. - (void)removeBlockImplementationForMethod:(SEL)selector;
  85. /** @name Block Class Method Implementations */
  86. /** The block that is to be fired when the specified
  87. selector is called on the delegating object's class.
  88. @param selector An encoded selector. Must not be NULL.
  89. @return A code block, or nil if no block is assigned.
  90. */
  91. - (id)blockImplementationForClassMethod:(SEL)selector;
  92. /** Assigns the given block to be fired when the specified
  93. selector is called on the reciever.
  94. @warning Starting with A2DynamicDelegate 2.0, a block will
  95. not be checked for a matching signature. A block can have
  96. less parameters than the original selector and will be
  97. ignored, but cannot have more.
  98. @param selector An encoded selector. Must not be NULL.
  99. @param block A code block with the same signature as selector.
  100. */
  101. - (void)implementClassMethod:(SEL)selector withBlock:(id)block;
  102. /** Disassociates any blocks so that nothing will be fired
  103. when the specified selector is called on the delegating
  104. object's class.
  105. @param selector An encoded selector. Must not be NULL.
  106. */
  107. - (void)removeBlockImplementationForClassMethod:(SEL)selector;
  108. @end