145 lines
4.9 KiB
Objective-C
145 lines
4.9 KiB
Objective-C
//
|
|
// A2DynamicDelegate.h
|
|
// BlocksKit
|
|
//
|
|
|
|
#import "BKDefines.h"
|
|
#import <Foundation/Foundation.h>
|
|
#import "NSObject+A2BlockDelegate.h"
|
|
#import "NSObject+A2DynamicDelegate.h"
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
/** A2DynamicDelegate implements a class's delegate, data source, or other
|
|
delegated protocol by associating protocol methods with a block implementation.
|
|
|
|
- (IBAction) annoyUser
|
|
{
|
|
// Create an alert view
|
|
UIAlertView *alertView = [[UIAlertView alloc]
|
|
initWithTitle:@"Hello World!"
|
|
message:@"This alert's delegate is implemented using blocks. That's so cool!"
|
|
delegate:nil
|
|
cancelButtonTitle:@"Meh."
|
|
otherButtonTitles:@"Woo!", nil];
|
|
|
|
// Get the dynamic delegate
|
|
A2DynamicDelegate *dd = alertView.bk_dynamicDelegate;
|
|
|
|
// Implement -alertViewShouldEnableFirstOtherButton:
|
|
[dd implementMethod:@selector(alertViewShouldEnableFirstOtherButton:) withBlock:^(UIAlertView *alertView) {
|
|
NSLog(@"Message: %@", alertView.message);
|
|
return YES;
|
|
}];
|
|
|
|
// Implement -alertView:willDismissWithButtonIndex:
|
|
[dd implementMethod:@selector(alertView:willDismissWithButtonIndex:) withBlock:^(UIAlertView *alertView, NSInteger buttonIndex) {
|
|
NSLog(@"You pushed button #%d (%@)", buttonIndex, [alertView buttonTitleAtIndex:buttonIndex]);
|
|
}];
|
|
|
|
// Set the delegate
|
|
alertView.delegate = dd;
|
|
|
|
[alertView show];
|
|
}
|
|
|
|
A2DynamicDelegate is designed to be 'plug and play'.
|
|
*/
|
|
@interface A2DynamicDelegate : NSProxy
|
|
|
|
/**
|
|
* The designated initializer for the A2DynamicDelegate proxy.
|
|
*
|
|
* An instance of A2DynamicDelegate should generally not be created by the user,
|
|
* but instead by calling a method in NSObject(A2DynamicDelegate). Since
|
|
* delegates are usually weak references on the part of the delegating object, a
|
|
* dynamic delegate would be deallocated immediately after its declaring scope
|
|
* ends. NSObject(A2DynamicDelegate) creates a strong reference.
|
|
*
|
|
* @param protocol A protocol to which the dynamic delegate should conform.
|
|
* @return An initialized delegate proxy.
|
|
*/
|
|
- (instancetype)initWithProtocol:(Protocol *)protocol;
|
|
|
|
/** The protocol delegating the dynamic delegate. */
|
|
@property (nonatomic, readonly) Protocol *protocol;
|
|
|
|
/** A dictionary of custom handlers to be used by custom responders
|
|
in a A2Dynamic(Protocol Name) subclass of A2DynamicDelegate, like
|
|
`A2DynamicUIAlertViewDelegate`. */
|
|
@property (nonatomic, strong, readonly) NSMutableDictionary *handlers;
|
|
|
|
/** When replacing the delegate using the A2BlockDelegate extensions, the object
|
|
responding to classical delegate method implementations. */
|
|
@property (nonatomic, weak, readonly, nullable) id realDelegate;
|
|
|
|
/** @name Block Instance Method Implementations */
|
|
|
|
/** The block that is to be fired when the specified
|
|
selector is called on the reciever.
|
|
|
|
@param selector An encoded selector. Must not be NULL.
|
|
@return A code block, or nil if no block is assigned.
|
|
*/
|
|
- (nullable id)blockImplementationForMethod:(SEL)selector;
|
|
|
|
/** Assigns the given block to be fired when the specified
|
|
selector is called on the reciever.
|
|
|
|
[tableView.dynamicDataSource implementMethod:@selector(numberOfSectionsInTableView:)
|
|
withBlock:NSInteger^(UITableView *tableView) {
|
|
return 2;
|
|
}];
|
|
|
|
@warning Starting with A2DynamicDelegate 2.0, a block will
|
|
not be checked for a matching signature. A block can have
|
|
less parameters than the original selector and will be
|
|
ignored, but cannot have more.
|
|
|
|
@param selector An encoded selector. Must not be NULL.
|
|
@param block A code block with the same signature as selector.
|
|
*/
|
|
- (void)implementMethod:(SEL)selector withBlock:(nullable id)block;
|
|
|
|
/** Disassociates any block so that nothing will be fired
|
|
when the specified selector is called on the reciever.
|
|
|
|
@param selector An encoded selector. Must not be NULL.
|
|
*/
|
|
- (void)removeBlockImplementationForMethod:(SEL)selector;
|
|
|
|
/** @name Block Class Method Implementations */
|
|
|
|
/** The block that is to be fired when the specified
|
|
selector is called on the delegating object's class.
|
|
|
|
@param selector An encoded selector. Must not be NULL.
|
|
@return A code block, or nil if no block is assigned.
|
|
*/
|
|
- (id)blockImplementationForClassMethod:(SEL)selector;
|
|
|
|
/** Assigns the given block to be fired when the specified
|
|
selector is called on the reciever.
|
|
|
|
@warning Starting with A2DynamicDelegate 2.0, a block will
|
|
not be checked for a matching signature. A block can have
|
|
less parameters than the original selector and will be
|
|
ignored, but cannot have more.
|
|
|
|
@param selector An encoded selector. Must not be NULL.
|
|
@param block A code block with the same signature as selector.
|
|
*/
|
|
- (void)implementClassMethod:(SEL)selector withBlock:(nullable id)block;
|
|
|
|
/** Disassociates any blocks so that nothing will be fired
|
|
when the specified selector is called on the delegating
|
|
object's class.
|
|
|
|
@param selector An encoded selector. Must not be NULL.
|
|
*/
|
|
- (void)removeBlockImplementationForClassMethod:(SEL)selector;
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|