Block块.
1.声明Block
int (^myBlock)(int n) = ^(int num)
类型 (^名称)(需要传的参数)= ^(参数)
2 __block 变量
在block块中修改block块外部变量的值,只有将外部的变量前面加_ _(两个短杠才能修改)
3 __weak 变量
在ARC机制下,如果block中应用控制器对象或者其实例变量,block会对其强引用,导致拷贝一份控制器对象从而造成内存泄露。为了避免这一问题,则需要:
__weak typeof(self)weakself = self;
block可以代替代理
控件类.h中声明block
@interface tapView : UIView
typedef void (^tapViewblock)(tapView * tapview);
@property (nonatomic, strong) tapViewblock block;
@property (nonatomic, strong) UIImageView * ima;
控件类.m中判断block块是否存在,如果存在则将控件类对象做参数
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
_ima = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
_ima.userInteractionEnabled = YES;
[self addSubview:_ima];
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(change:)];
[tap setNumberOfTapsRequired:1];
[tap setNumberOfTouchesRequired:1];
[_ima addGestureRecognizer:tap];
}
return self;
}
- (void) change:(UITapGestureRecognizer *)sender
{
if (_block)
{
_block(self);
}
}
在控制器.m中将控制器中控件类的对象传给block,并在block块中实现想要的功能
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor =[UIColor whiteColor];
__weak typeof(self)weakself = self;
for (int i = 0; i < 3 ; i ++)
{
tapView * imageV = [[tapView alloc] initWithFrame:CGRectMake(i * 80, 50, 80, 80)];
// imageV.delegate = self;
imageV.ima.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i + 1]];
[self.view addSubview:imageV];
imageV.block = ^(tapView * imag){
UIImageView * backimage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
backimage.image = imag.ima.image;
[self.view addSubview:backimage];
};
}
}
总结:代理其实和协议没啥两样,都是定义方法而自己不实现,但是自定义代理需要传值并且需要有调用定义方法的代码,而系统代理则直接传值且调用代理方法就可以了,无需使用自定义代码来调用代理方法;block块则为了实现控件想要达到的事件的更加简单的方法,我们使用block和自定义代理也有些类似,但是我们用block块无需定义协议,也无需调用代理,只是定义一个block块,判断block块存在时,将控件对象传给block。然后就在block块中实现控件想要实现的方法