遇到一个bug, 就是有很多很多图片, 比如5000以上的图片用collectionView去展示的时候, 飞快的滑动会卡死整个界面, 进而卡死整个应用.
我查了一下内存, 47m不多, 不太可能因为内存而卡死.
不知道是什么问题,我估计是collectionview内部对这种数据展示有问题吧
所以优化一下
1, 对runloop进行观察, 并进行事件优化
typedef void(^RunLoopBlock)(void);
-(void)addTask:(RunLoopBlock)block{
[_showTask addObject:block];
if (_showTask.count > _taskCount) {
[_showTask removeObjectAtIndex:0];
}
}
-(void)addRunLoopObserver{
CFRunLoopRef runloop = CFRunLoopGetCurrent();
CFRunLoopObserverContext context = {
0,
(__bridge void *)self,
&CFRetain,
&CFRelease,
NULL
};
static CFRunLoopObserverRef defaultModeObserver;
defaultModeObserver = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeWaiting, YES, 0, &RunLoopCallBack, &context);
CFRunLoopAddObserver(runloop, defaultModeObserver, kCFRunLoopCommonModes);
CFRelease(defaultModeObserver);
}
static void RunLoopCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info){
SSChoosePhotoViewController* vc = (__bridge SSChoosePhotoViewController*)info;
if (vc.showTask.count == 0) {
return;
}
RunLoopBlock task = vc.showTask.firstObject;
task();
[vc.showTask removeObjectAtIndex:0];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
SSChoosePhotoCollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([SSChoosePhotoCollectionViewCell class]) forIndexPath:indexPath];
JSDateModel* dateModel = self.itemsArray[indexPath.section];
JSImageModel *model = [dateModel.imageArray objectAtIndex:indexPath.row];
if ([_uploadArray containsObject:model]) {
cell.choosed = YES;
}else{
cell.choosed = NO;
}
if ([model.photoName hasSuffix:@".mp4"]) {
cell.isVideo = YES;
}else{
cell.isVideo = NO;
}
__weak typeof(self) weak_self = self;
[self addTask:^{
[weak_self showImage:cell model:model];
}];
return cell;
}
其实整个逻辑就是自己去针对整个图片加载逻辑优化,主要是用runloop的触发机制去触发UI渲染事件, 一般情况下, UI事件必须在主线程, 实际上底层就是Runloop, 自己控制任务数量(一般我自己设置为20), 这样在滑动的时候就会顺畅很多,而且不会出现卡死的情况
网友评论