1. 程式人生 > >block巢狀的資料繫結問題,block時序問題

block巢狀的資料繫結問題,block時序問題

做過幾個專案以後,會用到比較深層次的block,開始學習階段block都是通過mvc方式寫,不會涉及到block時序問題,也不會有資料來源繫結問題,因為controller不會被釋放,你的資料都寫在controller層。邁向大神的階段就需要多用block封裝view,資料只是在controller層獲取,傳到view層,在用block回撥到controller層,也經常性的會用baseview去做資料傳遞。先來看一下,實現的效果圖

                                                           


可以看到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的資料來源繫結問題,不論多複雜也不會在遇到問題