iOS

runtime初次尝试

"看到结果才会觉得努力是值得的"

Posted by 李勇 on 2017-06-05

背景介绍

学习Swift的时候写工具类的时候突发奇想,想要使用block代替selector,尝试了很多次,最后还是无能为力,后来想到在oc中遇到过BlocksKit,遂学习参考了一下,但是用到了runtime,无法在纯Swift的项目中使用,再次记录

方法比较

下面是在UIView的分类中声明的两个方法,为了给View添加一个点击事件,如同控件button一样,下面两个方法的效果一样

1
2
3
4
@interface UIView (Helper)
-(void)addTapAction:(SEL)action forTarget:(id) aTarget;
-(id)addTapActionBlock:(void (^)(id sender))action;
@end

下面是对两个方法的实现,第一个方法直接将sel传递,第二个方法是通过运行时的两个方法相当于先将block通过key保存起来然后再拿出来调用block(暂时先这么理解,因为我觉得不是那么简单,后面会更改见解)

1
2
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#import "UIView+Helper.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>
@implementation UIView (Helper)
-(void)addTapAction:(SEL)action forTarget:(id) aTarget
{
self.userInteractionEnabled=YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:aTarget action:action];
[self addGestureRecognizer:tap];
}
- (id)addTapActionBlock:(void (^)(id sender))action{
self.userInteractionEnabled=YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(testHandle:)];
[self addGestureRecognizer:tap];
if (!self) return nil;
objc_setAssociatedObject(self, @"qeqweqeqweqeweretertet", action, OBJC_ASSOCIATION_COPY_NONATOMIC);
return self;
}
- (void)testHandle:(id)sender{
void (^block)(id) = objc_getAssociatedObject(self, @"qeqweqeqweqeweretertet");
if (block) block(self);
}
@end