原文出处: talisk斯温的技术博客(@swaIn ) 设计模式
在iOS中,全部的UIControl标准控件使用到最广泛最传统的执行方法的方式就是Target-Action,中文通常称做目标-动做,是比较经常使用的一种设计模式。它的主要思想就是,在对象产生某个事件的特定时刻,给一个对象发送一个消息。就好像说『当talisk即将吃早饭的时候,swain去煎个蛋』。函数
其实Target-Action是很好用很方便的一个模式,但其最致命的一个缺点就是传值很麻烦,本文总结下这种模式的传值方式,并给出我认为最好的一个传值方式。atom
这是最简单的一个方式,tag
是一个无符号整型值,贯穿于全部UIKit控件,给控件加上tag
,在action方法里能够取到sender
,对sender
作强制类型转换便可拿到tag
。spa
Objective-C.net
1设计 |
[self.datePicker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged];code |
Objective-Corm
1对象 2blog 3 4 5 |
- (void)dateChange:(id)sender { if (((UIDatePicker *)sender).tag) { NSLog(@"tag0"); } } |
因为tag
是个无符号整型数值,也仅仅能传递一些简单数据。
sender
就是发起行为的对象,就像上面这段代码所写,当datePicker
的值发生变化的时候,调用self
的dateChange:
方法,这个方法默认参数就是sender
。
经过category给父类加上一些方法,使子类对象可以携带一些数据,这样对于开发者来讲就很自由了。
Objective-C
1 2 3 4 5 6 7 |
#import <Foundation/Foundation.h>
@interface NSObject (Extension)
@property (nonatomic,retain)NSDictionary *userInfo;
@end |
在头文件中,注明category和名称,加上咱们须要使用的数据的property。
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#import "NSObject+Extension.h" #import <objc/runtime.h>
@implementation NSObject (Extension)
- (void)setUserInfo:(NSDictionary *)_userInfo { objc_setAssociatedObject(self, @"userInfo", _userInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }
- (id)userInfo { return objc_getAssociatedObject(self, @"userInfo"); }
@end |
在实现文件中,要用到Objective-C的Runtime黑魔法了,经过使用objc_getAssociatedObject
和objc_setAssociatedObject
两个运行时函数的使用,动态地向NSObject
根类中添加了属性,这样,只要是继承自NSObject
而且引用了这个Category的地方,咱们均可以给对象添加userInfo这个属性,意味着咱们想传递什么就能够传递什么了。
在写完这个Category后,咱们在须要传值的地方,给对象设置好userInfo,便可。
Objective-C
1 2 |
[self.datePicker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged]; [self.datePicker setUserInfo:@{@"from": [NSDate date], @"to": [NSDate date]}]; |
Objective-C
1 2 3 |
- (void)dateChange:(id)sender { NSLog(@"%@", ((UIDatePicker *)sender).userInfo); } |
QQ技术交流群290551701