iOS
Multicast-Delegierte
Suche…
Einführung
Muster zum Hinzufügen von Multicasting-Funktionen zu vorhandenen iOS-Steuerelementen. Durch das Hinzufügen von Multicasting wird die Übersichtlichkeit und Wiederverwendung von Code verbessert.
Multicast-Delegaten für alle Steuerelemente
Leiten Sie Nachrichten von einem Objekt an ein anderes durch Delegierte weiter, und senden Sie diese Nachrichten an mehrere Beobachter.
Schritt 1: - Erstellen Sie die NSObject
Klasse von RRMulticastDelegate
Schritt 2: - Der folgende Code wird in der Datei RRMulticastDelegate.h
implementiert
#import <Foundation/Foundation.h>
@interface RRMulticastDelegate : NSObject
{
//Handle multiple observers of delegate
NSMutableArray* _delegates;
}
// Delegate method implementation to the list of observers
- (void)addDelegate:(id)delegate;
- (void)removeDelegate:(id)delegate;
// Get multiple delegates
-(NSArray *)delegatesObjects;
@end
Schritt 3: - Der folgende Code wird in der Datei RRMulticastDelegate.m
implementiert
#import "RRMulticastDelegate.h"
@implementation RRMulticastDelegate
- (id)init
{
if (self = [super init])
{
_delegates = [NSMutableArray array];
}
return self;
}
-(NSArray *)delegatesObjects
{
return _delegates;
}
- (void)removeDelegate:(id)delegate
{
if ([_delegates containsObject:delegate])
[_delegates removeObject:delegate];
}
- (void)addDelegate:(id)delegate
{
if (![_delegates containsObject:delegate])
[_delegates addObject:delegate];
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
if ([super respondsToSelector:aSelector])
return YES;
// if any of the delegates respond to this selector, return YES
for(id delegate in _delegates)
{
if (!delegate)
continue;
if ([delegate respondsToSelector:aSelector])
{
return YES;
}
}
return NO;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
// can this class create the sinature?
NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];
// if not, try our delegates
if (!signature)
{
for(id delegate in _delegates)
{
if (!delegate)
continue;
if ([delegate respondsToSelector:aSelector])
{
return [delegate methodSignatureForSelector:aSelector];
}
}
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
// forward the invocation to every delegate
for(id delegate in _delegates)
{
if (!delegate)
continue;
if ([delegate respondsToSelector:[anInvocation selector]])
{
[anInvocation invokeWithTarget:delegate];
}
}
}
@end
Schritt 4: - Erstellen Sie die NSObject
Kategorieklasse von RRProperty
Schritt 5: - Folgende NSObject+RRProperty.h
Datei NSObject+RRProperty.h
#import <Foundation/Foundation.h>
#import "RRMulticastDelegate.h"
@interface NSObject (RRProperty)<UITextFieldDelegate,UITableViewDataSource>
-(void)setObject:(id)block forKey:(NSString *)key;
-(id)objectForKey:(NSString *)key;
#pragma mark - Multicast Delegate
- (RRMulticastDelegate *)multicastDelegate;
- (RRMulticastDelegate *)multicastDatasource;
-(void)addDelegate:(id)delegate;
-(void)addDataSource:(id)datasource;
@end
Schritt 6: - Der folgende Code wird in der Datei NSObject+RRProperty.m
implementiert
#import "NSObject+RRProperty.h"
#import <objc/message.h>
#import <objc/runtime.h>
#pragma GCC diagnostic ignored "-Wprotocol"
static NSString *const MULTICASTDELEGATE = @"MULTICASTDELEGATE";
static NSString *const MULTICASTDATASOURCE = @"MULTICASTDATASOURCE";
@implementation NSObject (RRProperty)
-(void)setObject:(id)block forKey:(NSString *)key
{
objc_setAssociatedObject(self, (__bridge const void *)(key), block, OBJC_ASSOCIATION_RETAIN);
}
-(id)objectForKey:(NSString *)key
{
return objc_getAssociatedObject(self, (__bridge const void *)(key));
}
#pragma mark - Multicast Delegate
- (RRMulticastDelegate *)multicastDelegate
{
id multicastDelegate = [self objectForKey:MULTICASTDELEGATE];
if (multicastDelegate == nil) {
multicastDelegate = [[RRMulticastDelegate alloc] init];
[self setObject:multicastDelegate forKey:MULTICASTDELEGATE];
}
return multicastDelegate;
}
- (RRMulticastDelegate *)multicastDatasource
{
id multicastDatasource = [self objectForKey:MULTICASTDATASOURCE];
if (multicastDatasource == nil) {
multicastDatasource = [[RRMulticastDelegate alloc] init];
[self setObject:multicastDatasource forKey:MULTICASTDATASOURCE];
}
return multicastDatasource;
}
-(void)addDelegate:(id)delegate
{
[self.multicastDelegate addDelegate:delegate];
UITextField *text = (UITextField *) self;
text.delegate = self.multicastDelegate;
}
-(void)addDataSource:(id)datasource
{
[self.multicastDatasource addDelegate:datasource];
UITableView *text = (UITableView *) self;
text.dataSource = self.multicastDatasource;
}
@end
Schließlich können Sie Multicast-Dalegate für alle Steuerelemente verwenden ...
Für ex ...
Importieren Sie Ihre Viewcontroller-Klasse in die Datei NSObject+RRProperty.h
, um auf ihre Methoden zuzugreifen, um den Multicast-Delegaten / die Datenquelle festzulegen .
UITextView *txtView = [[UITextView alloc]initWithFrame:txtframe];
[txtView addDelegate:self];
UITableView *tblView = [[UITableView alloc]initWithFrame:tblframe];
[tblView addDelegate:self];
[tblView addDataSource:self];