iOS Block块语法的使用
2017-05-12 本文已影响19人
酒深巷子Ya
一、block基础,block块内对外部变量进行修改。
int *num = 10;
void(^block)() = ^(){
num = 15;
};
block();
//这个回报错误提示,没有使用__block修饰。
NSMutableArray *array = [NSMutableArray array];
void(^block)() = ^(){
NSObject *obj = [[NSObject alloc] init];
[array addObject:obj];
};
block();
//
某些场景下,我们需要在Block内部对外部变量进行修改。这时需要使用__block来修饰该变量实现在Block内部的修改,此时Block是复制其引用地址来实现访问的。
二、避免block的循环使用
这个问题只需要记住一点就OK了---防止Block循环引用就是要防止对象之间引用的闭环出现。
例子,就拿很多人在用的MJRefresh说起
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
self.page = 1;
[self.dataArr removeAllObjects];
[self loadData];
}];
若在MJRefresh的执行Block中调用当前self或其所属属性,一定要注意循环引用问题。我们简单分析下MJRefresh为什么会造成循环引用问题:
点击进入headerWithRefreshingBlock对应方法即可
#pragma mark - 构造方法
- (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock
{
MJRefreshHeader *cmp = [[self alloc] init];
cmp.refreshingBlock = refreshingBlock;
return cmp;
}
这里仅有三行代码,无非就是创建了下拉刷新部分View然后返回,这里比较重要的是cmp.refreshingBlock = refreshingBlock;这一句,这里的refreshingBlock是属于MJRefreshHeader的强引用属性,最后header会成为我们自己tableView的强引用属性mj_header,也就是说self.tableView强引用header, header强引用refreshingBlock,如果refreshingBlock里面强引用self,就成了循环引用,所以必须使用weakSelf,破掉这个循环。
解决方案大家应该也不陌生
__weak typeof(self) weakself = self;
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
__strong typeof(self) strongself = weakself;
strongself.page = 1;
[strongself.dataArr removeAllObjects];
[strongself loadData];
}];