在iOS中,所有的UIControl标准控件使用到最普遍最传统的执行方法的方式就是Target-Action,中文一般称作目标-动作,是比较常用的一种设计模式。它的主要思想就是,在对象产生某个事件的特定时刻,给一个对象发送一个消息。就好像说『当talisk即将吃早饭的时候,swain去煎个蛋』。

其实Target-Action是很好用很方便的一个模式,但其最致命的一个缺点就是传值很麻烦,本文总结下这种模式的传值方式,并给出我认为最好的一个传值方式。

给对象加tag

这是最简单的一个方式,tag是一个无符号整型值,贯穿于所有UIKit控件,给控件加上tag,在action方法里可以取到sender,对sender做强制类型转换即可拿到tag


Objective-C

1

[self.datePicker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged];



Objective-C

1

2

3

4

5

- (void)dateChange:(id)sender {

    if (((UIDatePicker *)sender).tag) {

        NSLog(@"tag0");

    }

}

由于tag是个无符号整型数值,也仅仅能传递一些简单数据。sender就是发起行为的对象,就像上面这段代码所写,当datePicker的值发生变化的时候,调用selfdateChange:方法,这个方法默认参数就是sender

给父类做category

通过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_getAssociatedObjectobjc_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);

}

转载于:https://blog.51cto.com/starliu/1763727