Switft PickerView 导致的页面加载缓慢问题

问题描述:

进入一个带有时间选择器的页面,使用模拟器时需要等待10s左右的时间,使用真机需要1s左右的时间,运行过程中查看内存CPU,发现CPU暴涨,内存也上涨。此行为很影响用户体验,所以需要解决这个问题。

前提:

要做一个页面显示时间,效果图如下:

Switft PickerView 导致的页面加载缓慢问题_第1张图片
效果图

因为要做到类似于无限循环的效果所以数据源设置为了 小时( 24 * 10) 分钟(60 * 10)

坑点:

因为要自定义文字颜色,所以就使用了下面这个代理方法

func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { 
  return NSAttributedString(string: "test",
                                  attributes: [
                                    NSAttributedString.Key.foregroundColor: UIColor.white, //白色文字
                                    NSAttributedString.Key.textEffect:
                                        NSAttributedString.TextEffectStyle.letterpressStyle
            ])
}

看起来代码都很正常,因为之前并没有使用模拟器运行,所以这个问题不是很明显(真机效果会好很多),直到今天使用了模拟器运行,点一下emmmm,可以停顿给十几秒。然后就开始了一通查找。

如何定位的:

  • 先是把多余的代码通通注释,定位是UI问题还是其他问题

  • 定位到UI之后,把部分UI代码注释掉,定位到具体UI

  • 然后就定位到pickerView,继续查看其他的代码,猜测可能是因为数据源量过大引起

  • 改小数据量之后,稍微好转, 但还是有问题,怀疑复用问题

  • 然后就发现上面的这个代理并没有复用问题,怀疑NSAttributedString创建出了问题,于是把代理改为了

        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return "test"
        }
    
  • 发现速度立马恢复,于是定位到NSAttributedString

    后查阅资料得知NSAttributedString.TextEffectStyle.letterpressStyle这个东西会给字体加上阴影和高光,所以CPU在处理的时候需要耗费大量资源。

解决方案:

  • 1 使用另外的代理方法
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return "test"
    }

上述方法可以优化性能,但是字体颜色并未修改,所以优先级低

  • 2 把 NSAttributedString.TextEffectStyle.letterpressStyle效果去掉
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { 
  return NSAttributedString(string: "test",
                                  attributes: [
                                    NSAttributedString.Key.foregroundColor: UIColor.white
            ])
}

上述修改方案可以解决该问题,优先级高

  • 3 在换一个代理方法
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { .... return View; }

上述修改方案可以解决该问题,优先级高

你可能感兴趣的:(Switft PickerView 导致的页面加载缓慢问题)