【问题标题】:Massive CPU overuse whenever I push ViewController - Swift - Programmatically每当我推送 ViewController - Swift - 以编程方式时,大量 CPU 过度使用
【发布时间】:2020-08-06 21:21:41
【问题描述】:

每当我从 navigationController 推送新的 ViewController 时,我的 CPU 级别都很高。

我使用了 Time Profiler 工具,结果发现导致 CPU 过度使用的问题与我嵌入在 rootViewController 中的 ViewController 有关。

我说的ViewController如下:

class QuoteGeneratorController : UIViewController {

let interactiveShowTextView : UITextView = {
   let textView = UITextView()
    textView.font = UIFont(name: "avenir-black", size: 35)
    textView.textColor = .white
    textView.textAlignment = .left
    textView.textContainer.maximumNumberOfLines = 3
    textView.backgroundColor = .clear
    textView.isEditable = false
    textView.isSelectable = false
    textView.isUserInteractionEnabled = false
    return textView
}()

let progressBar : UIProgressView = {
    let progressView = UIProgressView(progressViewStyle: .bar)

    progressView.trackTintColor = UIColor.clear
    progressView.tintColor = UIColor.white

    return progressView
}()


let quotesArray = ["Hello", "Hello2", "Hello3"]


override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    print("I'm called")
    view.subviews.forEach { subview in
        subview.layer.masksToBounds = true
        subview.layer.cornerRadius = progressBar.frame.height / 2.0
    }
    
}

override func viewDidAppear(_ animated: Bool) {
    
    
    setUpAnimation()
}


override func viewDidLoad() {
    setUpUI()
    
    setUpAnimation()
}


fileprivate func setUpUI(){
    view.addSubview(interactiveShowTextView)
    view.addSubview(progressBar)
   
    interactiveShowTextView.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: view.leadingAnchor, bottom: nil, trailing: view.trailingAnchor)
    interactiveShowTextView.heightAnchor.constraint(equalToConstant: 150).isActive = true
    
    progressBar.anchor(top: interactiveShowTextView.bottomAnchor, leading: interactiveShowTextView.leadingAnchor, bottom: nil, trailing: nil, padding: .init(top: 10, left: 0, bottom: 0, right: 0), size: .init(width: 70, height: 9))
    
    
}

var iterator : Int = 0


fileprivate func setUpAnimation(){
    
    switch iterator {
    case 0:
        animateAndIterate()

    case 1:
        animateAndIterate()

    case 2:
        animateAndIterate()

    default:

        self.iterator = 0
        self.setUpAnimation()

}

}

fileprivate func animateAndIterate(){
    UIView.animate(withDuration: 0.0, animations: {
        self.progressBar.layoutIfNeeded()
    }, completion: { finished in
        self.progressBar.progress = 1.0
        self.interactiveShowTextView.text = self.quotesArray[self.iterator]
        self.interactiveShowTextView.fadeIn()
        UIView.animate(withDuration: 3, delay: 0.0, options: [.curveLinear], animations: {
            self.progressBar.layoutIfNeeded()
            self.perform(#selector(self.afterAnimation), with: nil, afterDelay: 2.5)
        }, completion: { finished in
            self.interactiveShowTextView.fadeOut()
            self.progressBar.progress = 0
            self.iterator = self.iterator + 1
            self.setUpAnimation()
        })
    })
    
}

@objc func afterAnimation() {
    self.interactiveShowTextView.fadeOut()
}
}

我实际上不知道是什么导致了这个问题,而且由于我是时间分析器的新手,但我认为你们中的一些人在开发过程中遇到了相同的过程。

在 Time Profiler 中,我得到了以下指示:

【问题讨论】:

    标签: swift uiviewcontroller uitextview cpu-usage pushviewcontroller


    【解决方案1】:

    使用完成块时,建议使用对结果的弱引用。否则,ARC 将计算您在这些块中使用的每个引用。

    像这样使用闭包:

    view.subviews.forEach { [weak self] subview in
        subview.layer.masksToBounds = true
        subview.layer.cornerRadius = progressBar.frame.height / 2.0
    }
    
    // (...)
    
    fileprivate func animateAndIterate() {
        UIView.animate(withDuration: 0.0, 
                         animations: { [weak self] in
            self?.progressBar.layoutIfNeeded()
        }, completion: { [weak self] finished in
            self?.progressBar.progress = 1.0
            self?.interactiveShowTextView.text = self.quotesArray[self.iterator]
            self?.interactiveShowTextView.fadeIn()
            UIView.animate(withDuration: 3, 
                                  delay: 0.0, 
                                options: [.curveLinear], 
                             animations: { [weak self] in
                self?.progressBar.layoutIfNeeded()
                self?.perform(#selector(self.afterAnimation), 
                              with: nil, afterDelay: 2.5)
            }, completion: { finished in
                self?.interactiveShowTextView.fadeOut()
                self?.progressBar.progress = 0
                self?.iterator = self.iterator + 1
                self?.setUpAnimation()
            })
        })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      • 2017-08-20
      • 2015-08-16
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      相关资源
      最近更新 更多