普通selector函数的传参

performSelector

可以传0, 1, 2个参数,更多的参数可以打包成NSDictionary传递。

1
2
3
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

NSInvocation

可以传任意个参数,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (NSString *) invocationActionWithStr: (NSString *) str andBlock: (NSString * (^) (NSString *)) blk
{
blk(str);
return str;
}
NSString *str = @"Here we go!";
NSString * (^invocationBlk) (NSString *) = ^NSString *(NSString *str){
NSLog(@"%@", str);
return str;
};
SEL selector = @selector(invocationActionWithStr:andBlock:);
NSMethodSignature *sign = [self methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sign];
invocation.selector = selector;
// 参数下标一般从2开始,0号参数为self,1号参数为_cmd
[invocation setArgument:&str atIndex:2];
[invocation setArgument:&invocationBlk atIndex:3];
[invocation invokeWithTarget:self];
// 获取返回值
NSString * __unsafe_unretained returnStr = @"Default";
// 可以人为修改返回值,甚至可以改变类型
// [invocation setReturnValue:&returnStr];
[invocation getReturnValue:&returnStr];
NSLog(@"Return: %@", returnStr);

UIButton的addTarget函数

一般是使用关联对象,有两种方法

定义分类

在分类中定义自己想要的对象实例,然后直接在target中调用sender.objectxxx即可,参见Objective-C与Runtime

动态绑定

即在代码中动态绑定需要的对象,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
- (void) taskAction: (id) sender
{
NSLog(@"%@", [objc_getAssociatedObject(sender, @"Btn") objectForKey:@"first"]);
}
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[btn setBackgroundColor:[UIColor blackColor]];
// tag属性只能传递简单的UIUIInteger类型的对象
btn.tag = 12;
NSDictionary *paramDic = @{@"first": self};
objc_setAssociatedObject(btn, @"Btn", paramDic, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[btn addTarget:self action:@selector(taskAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];

NSTimer的scheduledTimerWithTimeInterval函数

使用userInfo即可,示例如下:

1
2
NSDictionary *paramDic = @{@"first": self};
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:paramDic repeats:YES];