美文网首页IOSiOS学习笔记程序员
iOS | mutableCopy的实际运用

iOS | mutableCopy的实际运用

作者: Lol刀妹 | 来源:发表于2018-05-08 21:46 被阅读662次

    这是一篇发现问题和解决问题的笔记。

    遇到的问题

    每次上拉加载更多完成执行[self.tableView reloadData]后,banner都会增加两页。

    banner是一个cell,它的setModel方法代码是这样的:

    - (void)setModel:(CWFSpecialSaleBannerModel *)model {
        _model = model;
        
        self.pageControl.numberOfPages = _model.banners.count;
        
        if (_model.banners.count == 0) {
            [self.collectionView reloadData];
            return;
        }
        
        CWFSpecialSaleBannerItemModel *firstModel = model.banners.lastObject;
        CWFSpecialSaleBannerItemModel *lastModel = model.banners.firstObject;
        
        [_model.banners addObject:lastModel];
        [_model.banners insertObject:firstModel atIndex:0];
        
        [self.collectionView reloadData];
        
        if (self.collectionView.contentOffset.x == 0) {
            self.collectionView.contentOffset = CGPointMake(self.bounds.size.width, 0);
        }
        
        [self resetTimer];
    }
    

    这里首尾添加两个元素是为了做轮播效果。

    问题所在

    setModel的时候

     _model = model;
    

    这句代码乍看之下好像没什么问题,但是:

    CWFSpecialSaleBannerItemModel *firstModel = model.banners.lastObject;
    CWFSpecialSaleBannerItemModel *lastModel = model.banners.firstObject;
    
    [_model.banners addObject:lastModel];
    [_model.banners insertObject:firstModel atIndex:0];
    

    我的本意是给_model的banners数组添加两个元素,但这同时,也无意中给model的banners数组添加了两个元素,这就导致每次上拉加载更多[tableView reloadData]时调用banner cell的setModel都会给数据源里的model.banners数组增加两个元素。

    解决问题

    我想要的效果是对_model执行操作并不影响model

    想要一个相同的对象,但是对它进行操作又不影响原对象,自然而然想到了深拷贝,但是并不是所有类的对象都像NSArray对象具有深拷贝资格,只有遵从了NSMutableCopying协议的类的对象才能深拷贝。

    所以要对model进行改写:

    @interface CWFSpecialSaleBannerModel ()<NSMutableCopying>
    
    @end
    
    @implementation CWFSpecialSaleBannerModel
    
    - (id)mutableCopyWithZone:(NSZone *)zone {
        CWFSpecialSaleBannerModel *model = [[[self class] allocWithZone:zone] init];
        // 这里也要mutableCopy哦
        model.banners = self.banners.mutableCopy;
        return model;
    }
    
    @end
    

    setModel的时候,使用深拷贝的model:

    - (void)setModel:(CWFSpecialSaleBannerModel *)model {
        _model = model.mutableCopy;
        // ....
    }
    

    这样就不会因为改动_model而导致数据源的改动了。

    总结

    以前关于深浅拷贝的博客没有白看。

    你看完我的这篇笔记后相信有了更深刻的认识。

    不说了,吃鸡

    相关文章

      网友评论

      • Corbin___:如果你的model要这样用,属性约束词用copy应该也可以
        Lol刀妹:可以,反正就是弄个新对象出来
      • 编码的哲哲:所以,封面图的小姐姐是谁?
        编码的哲哲:@无夜之星辰 噗…我还以为是你:sweat_smile::sweat_smile:,居然有这么漂亮的程序员小姐姐
        Lol刀妹:@编码的哲哲 允儿
      • 陈藩:还没遇到这样的问题,不过提供了一个好的方法,下次遇到可以试下。感谢作者。
        Lol刀妹:@陈藩 :stuck_out_tongue_closed_eyes:
      • 魔法黛:看完镇楼美女,立马走人~~
        Lol刀妹:@魔法黛 点个赞再走也不迟
      • b2f70a645712:记得最后一句话 晚上一起吃鸡啊

      本文标题:iOS | mutableCopy的实际运用

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