天天看点

block嵌套的数据绑定问题,block时序问题

做过几个项目以后,会用到比较深层次的block,开始学习阶段block都是通过mvc方式写,不会涉及到block时序问题,也不会有数据源绑定问题,因为controller不会被释放,你的数据都写在controller层。迈向大神的阶段就需要多用block封装view,数据只是在controller层获取,传到view层,在用block回调到controller层,也经常性的会用baseview去做数据传递。先来看一下,实现的效果图

block嵌套的数据绑定问题,block时序问题

可以看到tableview的cell中会有下架按钮,这个是一个block回调。一个高水平的ios开发者实现tableview不再直接通过tableview的代理方法来实现,而是自己将tableview的代理封装到baseview中。然后通过block回调来实现tableview的代理方法。下面通过代码来复现一下遇到的问题。

-(void)tableViewBuild
{
    
    WS(weakSelf);
    [self setCellInitCustomizer:^(UITableViewCell *cell, id cellData, NSInteger index){
        
        ShopListCell * shopcell = [[ShopListCell alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, 209)];
        ShopListBean * shoplistBean =  cellData ;
        
        shopcell.tapblock = ^(NSInteger tag) {
            if (tag == 102) {
                NSLog(@"点击下架");
                [HomePageViewController requestXiajiaGoodsId:ShopListBean.goods_id withProduct_id:ShopListBean.product_id];
                [weakSelf requestShopList];

            }else if (tag == 103){ 
                
                [HomePageViewController requestShareInfoWithGoodsId:bean.goods_id andProductId:bean.product_id];
                
            }
            
        };
        [shopcell updateViewWithBean:shoplistBean];

        [cell addCustomerView:shopcell];
        
        
        
    }];
           

可以看到这个一个block回调,是初始化自定义cell,然后这个cell会有一个点击事件,也是一个block回调。那么问题来了。这个问题就是数据源绑定问题。block的难点之一。遇到的问题,就是点击下架,传递的商品id是上一个已经删除的商品。这就是block数据源绑定的问题。这是原来的写法。

解决问题,为什么出现了错乱的问题。因为tableviwe回调回来的数据源只是初始化的时候当你删除过一次,数据源就发生了对不上的问题。所以要确定cell的block传递过来的数据源就是当前cell 的。这样我们就需要对数据源多做一次处理,将代码修改如下。使用cell层传过来的数据模型;

shopcell.tapblock = ^(NSInteger tag,ShopListBean * bean) {
            if (tag == 102) {
                NSLog(@"点击下架");
                [HomePageViewController requestXiajiaGoodsId:bean.goods_id withProduct_id:bean.product_id];
                [weakSelf requestShopList];

            }
           

在初始化cell回调中的update函数中,已经将对应的数据源传递过去,所以我们在cell层记录一下,然后放到cell的属性中。使用cell点击事件的时候 再将这个属性回传回来,这样就不会出现block的时序问题,已经数据源错乱问题

-(void)updateViewWithBean:(ShopListBean*)bean{
    [_LeftIV sd_setImageWithURL:[NSURL URLWithString:bean.url]];
    _goodsTitle.text = bean.name;
    _bean = bean ;}
           
-(void)btnClick:(UIButton *)sender{
    if (_tapblock) {
        _tapblock(sender.tag,_bean);
    }
}
           

理解了这个block的数据源绑定问题,不论多复杂也不会在遇到问题