我注意到了一件奇怪的事情:就挂起/恢复后执行UIImage.drawAt
而言,UIView的速度变慢了两倍。按下Home键并返回到应用程序后,我发现模拟器和iOS 9-13上的设备的FPS下降了2倍。就String.drawAt
或填充矩形而言,它的功能保持不变(这也使我在恢复后重新启动时出现一些错误的可能性降低了。)
谁能解释为什么以及如何解决?恢复简历后重新创建视图可解决此问题,但我宁愿使用现有实例。
下面是一个简短的示例。您只需要将一些图像添加到资产中(我是具有透明性的112x145 PNG)。如果您的图片太小,示例应用程序显示60 FPS,请在最后一种方法中增加max
参数。
编辑确保将图像包括在所有x1,x2,x3中,以便加载原始分辨率。否则,升级将是最慢的操作,而不是绘图。
// AppDelegate.swift
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder,UIApplicationDelegate
{
var window: UIWindow?
func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?)->Bool
{
self.window=UIWindow(frame: UIScreen.main.bounds)
window!.makeKeyAndVisible()
let testViewController=TestViewController()
window!.rootViewController=testViewController
Runner._instance.testViewController=testViewController
return true
}
func applicationDidEnterBackground(_ application: UIApplication)
{
Runner._instance.stop()
}
func applicationDidBecomeActive(_ application: UIApplication)
{
Runner._instance.start()
}
func applicationWillTerminate(_ application: UIApplication)
{
Runner._instance.stop()
}
}
class Runner: NSObject
{
static let _instance=Runner()
var testViewController: TestViewController!
var displayLink: CADisplayLink!
var fps=0
var lastFpsCounterTime=Date().timeIntervalSince1970
var fpsCounter=0
func start()
{
if displayLink == nil
{
displayLink=CADisplayLink(target: self,selector: #selector(Runner.run))
displayLink.add(to: RunLoop.main,forMode: RunLoop.Mode.common)
}
}
func stop()
{
displayLink?.invalidate()
displayLink=nil
}
@objc func run()
{
if lastFpsCounterTime+1<Date().timeIntervalSince1970
{
fps=fpsCounter
lastFpsCounterTime=Date().timeIntervalSince1970
fpsCounter=0
}
fpsCounter+=1
testViewController.view.setNeedsDisplay()
}
}
class TestViewController: UIViewController
{
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
loadView()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
{
super.init(nibName: nibNameOrNil,bundle: nibBundleOrNil)
loadView()
}
override func loadView()
{
view=TestView(frame: UIScreen.main.bounds)
}
}
class TestView: UIView
{
let image=UIImage(named: "card")!
required init?(coder: NSCoder)
{
super.init(coder: coder)
}
override init(frame: CGRect)
{
super.init(frame: frame)
isOpaque=true
}
override func draw(_ _rect: CGRect)
{
let context=UIGraphicsGetCurrentContext()!
context.setFillColor(red: 1, green: 1, blue: 1, alpha: 1)
context.fill(bounds)
let max=50 //Choose max high enough to get less than 60 FPS
let time=Date().timeIntervalSince1970
for i in 1...max
{
//image.draw(at: ) is affected by suspend/resume, but "String".draw(at: ) is not
image.draw(at: CGPoint(x: (image.size.width+bounds.width)*CGFloat(time.truncatingRemainder(dividingBy: Double(1+i))/Double(1+i))-image.size.width,y: bounds.height*CGFloat(i)/CGFloat(max)))
}
let font=UIFont(name: "Arial", size: 15)!
let textFontAttributes=[NSAttributedString.Key.font: font,
NSAttributedString.Key.foregroundColor: UIColor(red: 1, green: 0, blue: 0, alpha: 1),
NSAttributedString.Key.paragraphStyle: NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle]
"FPS: \(Runner._instance.fps)".draw(at: CGPoint(x: 2,y: 30),withAttributes: textFontAttributes)
}
}