美文网首页
记录一次cell的block捕获model引发的bug

记录一次cell的block捕获model引发的bug

作者: YannChee | 来源:发表于2020-03-09 18:03 被阅读0次

    下面这段代码乍一看没什么问题,其实会造成cell.buyBtnClick 捕获model的问题,造成点击按钮model不是正确model的bug

    bug代码:

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        QYMyCourseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"QYMyCourseCell" forIndexPath:indexPath];
        QYMyHomeCourseSubjectModel*  subjectModel = [self.dataList safeObjectAtIndex:indexPath.section];
           QYMyHomeCourseModel*  model = [subjectModel.list safeObjectAtIndex:indexPath.item];
           cell.model = model;
           @weakify(self);
           if (!cell.buyBtnClick) {
               cell.buyBtnClick = ^{
                   @strongify(self);
                   NSString *name = model.title;
                   [[[UIAlertView alloc] initWithTitle:nil message:name delegate:nil cancelButtonTitle:@"0k" otherButtonTitles:nil, nil] show];
               };
           }
        return cell;
    }
    

    来分析下这段代码:
    由于block的实现是写在- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath,这个代理方法里面,
    这个方法调用会很频繁,所以在cell的block的实现上加上 if (!cell.buyBtnClick) { .... } 的判断没有问题,可以避免block频繁创建的赋值,提升性能; 但是由于cell的复用机制,当列表中cell比较多时,cell循环利用,cell捕获的之前cell的model而不是当前的model.

    正确的写法应该是,把model 作为cell的block的参数回调回来

    @interface QYMyCourseCell : UICollectionViewCell
    @property(nonatomic, strong) void (^buyBtnClick)(QYMyHomeCourseModel *model);
    @end
    
    @implementation DTMyCourseViewController
     @weakify(self);
        [self.buyBtn setBlockForControlEvents:UIControlEventTouchUpInside block:^(id _Nonnull sender) {
            @strongify(self);
            !self.buyBtnClick ? : self.buyBtnClick(self.model);
        }];
    @end
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        QYMyCourseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"QYMyCourseCell" forIndexPath:indexPath];
        QYMyHomeCourseSubjectModel*  subjectModel = [self.dataList safeObjectAtIndex:indexPath.section];
           QYMyHomeCourseModel*  model = [subjectModel.list safeObjectAtIndex:indexPath.item];
           cell.model = model;
           @weakify(self);
           if (!cell.buyBtnClick) {
               cell.buyBtnClick = ^(QYMyHomeCourseModel * _Nonnull cellModel) {
                   @strongify(self);
                   NSString *name = cellModel.title;
                   [[[UIAlertView alloc] initWithTitle:nil message:name delegate:nil cancelButtonTitle:@"0k" otherButtonTitles:nil, nil] show];
               };
           }
        return cell;
    }
    

    这样cell中的按钮点击时,回调回来的,永远是当前cell的model.

    相关文章

      网友评论

          本文标题:记录一次cell的block捕获model引发的bug

          本文链接:https://www.haomeiwen.com/subject/ghapdhtx.html