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

本文探讨了iOS开发中使用Block进行数据源绑定时遇到的问题及解决方案,详细介绍了如何通过Block回调更新UITableView,并解决了因数据源错乱导致的显示异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做过几个项目以后,会用到比较深层次的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的数据源绑定问题,不论多复杂也不会在遇到问题



" 端口对齐脚本 ver 1.3(空格对齐版) function! AlignVerilogPorts() let s:max_type = 0 let s:max_reg = 0 let s:max_bits = 0 let s:max_name = 0 let s:port_list = [] " 第一阶段:定位端口块范围 normal! gg call search('module\s\+\w*(\s*$', 'W') normal! j let start_line = line('.') call search(');', 'W') normal! k let end_line = line('.') let port_block_lines = getline(start_line, end_line) " 第二阶段:解析内容 for raw_line in port_block_lines let line = substitute(raw_line, '\s*$', '', '') " 清理行尾空格 " 处理独立注释行 if line =~ '^\s*//' call add(s:port_list, {'type': 'comment', 'content': line}) continue endif " 处理端口声明 let clean_line = substitute(line, '\s*//.*$', '', '') " 移除行尾注释 let clean_line = substitute(clean_line, '^\s*,', '', '') " 移除行首逗号 let parts = matchlist(clean_line, \ '^\s*\(input\|output\|inout\)\s\+\(reg\|wire\)\?\s*\(\[.*\]\)\?\s*\(\w\+\)') if !empty(parts) " 提取端口元素(处理bits字段中的Tab) let type = parts[1] let regwire = !empty(parts[2]) ? parts[2] : '' let bits = !empty(parts[3]) ? substitute(parts[3], '\t', ' ', 'g') : '' let name = parts[4] let comment = matchstr(line, '//.*$') " 保留原始注释 " 更新对齐参数 let s:max_type = max([s:max_type, len(type)+1]) let s:max_reg = max([s:max_reg, len(regwire)+1]) let s:max_bits = max([s:max_bits, len(bits)]) let s:max_name = max([s:max_name, len(name)]) " 存储端口信息 call add(s:port_list, { \ 'type': 'port', \ 'port_type': type, \ 'regwire': regwire, \ 'bits': bits, \ 'name': name, \ 'comment': comment}) endif endfor " 第三阶段:生成对齐内容 let formatted = [] let cnt = 0 for item in s:port_list if item.type == 'comment' call add(formatted, item.content) else let port = item let prefix = (cnt == 0) ? ' ' : ' ,' " 各字段对齐处理(强制使用空格) let type_str = printf('%-'.s:max_type.'s', port.port_type) let reg_str = printf('%-'.s:max_reg.'s', port.regwire) let bit_str = printf('%-'.s:max_bits.'s', port.bits) let name_str = printf('%-'.s:max_name.'s', port.name) " 组合完整行并清理Tab let line = prefix . type_str . reg_str . bit_str . ' ' . name_str if !empty(port.comment) let line .= ' ' . port.comment endif let line = substitute(line, '\t', ' ', 'g') " 全局替换Tab为空格 call add(formatted, substitute(line, '\s\+$', '', '')) let cnt += 1 endif endfor " 第四阶段:替换原始内容 execute start_line.','.end_line.'d' call append(start_line-1, formatted) endfunction " 快捷键绑定建议(按需启用) " nnoremap <silent> <leader>al :call AlignVerilogPorts()<CR> 根据下面的要求,优化以上脚本。 1.能兼容parameter的定义 2.其他功能保持不变
最新发布
03-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值