这是一篇发现问题和解决问题的笔记。
遇到的问题
每次上拉加载更多完成执行[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而导致数据源的改动了。
总结
以前关于深浅拷贝的博客没有白看。
你看完我的这篇笔记后相信有了更深刻的认识。
作者:无夜之星辰
链接:https://www.jianshu.com/p/b3d392a9e71c
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦