服务报价 | 域名主机 | 网络营销 | 软件工具| [加入收藏]
当前位置: 主页 > 开发教程 > ios开发教程 >

iOS消息传递之Target-Action

时间:2016-11-08 15:24来源:未知 作者:好模板 点击:
一个应用 ,一般都会有很多对象,对象与对象之间避免不了进行消息传递。说到消息传递,肯定是相互的,即由A传到B,也可以由B传的A。 iOS下,有以下消息传递方式: 属性(Get/Set)

一个应用 ,一般都会有很多对象,对象与对象之间避免不了进行消息传递。说到消息传递,肯定是相互的,即由A传到B,也可以由B传的A。

iOS下,有以下消息传递方式:

  1. 属性(Get/Set)
  2. 方法(Public)
  3. KVO
  4. Target-Action
  5. 通知(NSNotification)
  6. 代理(DataSource/Delegate,其实是Protocol)
  7. Block

这篇文章主要介绍Target-Action,其他方法这里暂不介绍。

先来看以下Target-Action在系统提供的Framework中都有哪些使用。

  1. UIKit.framework 
    有UIControl以及其子类(比如UIButton、UISwitch等)
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(0.0, 0.0, 100.0, 50.0);
    [btn addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
  2. Foundation.framework 
    有NSNotification、NSTimer
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:@"TEST" object:nil];
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(test) userInfo:nil repeats:NO];
    上面提及到的示例,相信大家都有所了解,这里不多介绍,直接提需求,如果我们想自己实现Target-Action该如何做? 
    直接上代码

方案1:

#import <Foundation/Foundation.h>
//
@interface Manager : NSObject
//
-(void)addTarget:(id)aTarget selector:(SEL)aSelector;
@end
#import "Manager.h"
//
@interface Manager ()
//
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL selector;
@end
//
@implementation Manager
//
-(id)init {
    self = [super init];
    if (self) {
        //
    }
    return self;
}
//
 (void)addTarget:(id)aTarget selector:(SEL)aSelector {
    _target = aTarget;
    _selector = aSelector;
}
@end

方案2

#import <Foundation/Foundation.h>
//
@interface Manager : NSObject
//
-(void)addTarget:(id)aTarget selector:(SEL)aSelector forEvent:(NSInteger)aEvent;
-(void)removeTarget:(id)aTarget forEvent:(NSInteger)aEvent;
@end
#import "Manager.h"
//
@interface Manager ()
//
@property (nonatomic, strong) NSMutableDictionary *targetDict;
@end
//
@implementation Manager
//
-(id)init {
    self = [super init];
    if (self) {
        _targetDict = [[NSMutableDictionary alloc] initWithCapacity:0];
    }
    return self;
}
//
-(void)addTarget:(id)aTarget selector:(SEL)aSelector forEvent:(NSInteger)aEvent {
    NSString *key = [NSString stringWithFormat:@"%zd",aEvent];
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:0];
    [dict setValue:aTarget forKey:@"target"];
    [dict setValue:NSStringFromSelector(aSelector) forKey:@"action"];
    [_targetDict setValue:dict forKey:key];
}
//
-(void)removeTarget:(id)aTarget forEvent:(NSInteger)aEvent {
    NSString *key = [NSString stringWithFormat:@"%zd",aEvent];
    if ([[_targetDict allKeys] containsObject:key]) {
        [_targetDict removeObjectForKey:key];
    }
}
@end

方案3

#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN

@interface WeakProxy : NSProxy
//
@property (nullable, nonatomic, weak, readonly) id target;
//
-(instancetype)initWithTarget:(id)target;
+(instancetype)proxyWithTarget:(id)target;

NS_ASSUME_NONNULL_END
@end
#import "WeakProxy.h"

@implementation WeakProxy

- (instancetype)initWithTarget:(id)target {
    _target = target;
    return self;
}

+ (instancetype)proxyWithTarget:(id)target {
    return [[WeakProxy alloc] initWithTarget:target];
}

- (id)forwardingTargetForSelector:(SEL)selector {
    return _target;
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    void *null = NULL;
    [invocation setReturnValue:&null];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    return [_target methodSignatureForSelector:selector];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    return [_target respondsToSelector:aSelector];
}
@end
#import <Foundation/Foundation.h>

@interface Manager : NSObject

- (void)addTarget:(id)aTarget selector:(SEL)aSelector forEvent:(NSInteger)aEvent;
- (void)removeTarget:(id)aTarget forEvent:(NSInteger)aEvent;

@end
#import "Manager.h"
#import "WeakProxy.h"

@interface Manager ()

@property (nonatomic, strong) NSMutableDictionary *targetDict;

@end

@implementation Manager

- (id)init {
    self = [super init];
    if (self) {
        _targetDict = [[NSMutableDictionary alloc] initWithCapacity:0];
    }
    return self;
}

- (void)addTarget:(id)aTarget selector:(SEL)aSelector forEvent:(NSInteger)aEvent {
    WeakProxy *proxy = [WeakProxy proxyWithTarget:aTarget];

    NSString *key = [NSString stringWithFormat:@"%zd",aEvent];
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:0];
    [dict setValue:proxy forKey:@"target"];
    [dict setValue:NSStringFromSelector(aSelector) forKey:@"action"];
    [_targetDict setValue:dict forKey:key];
}

- (void)removeTarget:(id)aTarget forEvent:(NSInteger)aEvent {
    NSString *key = [NSString stringWithFormat:@"%zd",aEvent];
    if ([[_targetDict allKeys] containsObject:key]) {
        [_targetDict removeObjectForKey:key];
    }
}

@end

好啦,到这我想到的解决方案就是这些了。有兴趣的可以比较方案1、2、3的区别!!

(责任编辑:好模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容