iOS UIView在挂起/恢复后变慢
我注意到一件奇怪的事情:在挂起/恢复后,UIView在执行iOS UIView在挂起/恢复后变慢,ios,swift,uiview,uiimage,core-graphics,Ios,Swift,Uiview,Uiimage,Core Graphics,我注意到一件奇怪的事情:在挂起/恢复后,UIView在执行UIImage.drawAt方面的速度慢了两倍。在按下Home键并返回应用程序后,我在iOS 9-13的模拟器和设备上看到FPS下降了2倍。它在String.drawAt或填充矩形方面的能力保持不变(在恢复后重新启动时,它也不太可能犯我的错误) 有人能解释为什么以及如何修复它吗?恢复后重新创建视图修复了问题,但我宁愿使用现有实例 下面是一个简短的例子。您只需要将一些图像添加到资源中(我的是112x145 PNG,具有透明度)。如果您的图像
UIImage.drawAt
方面的速度慢了两倍。在按下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)
}
}
//AppDelegate.swift
导入UIKit
@UIApplicationMain
类AppDelegate:UIResponder、UIApplicationLegate
{
变量窗口:UIWindow?
func应用程序(application:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplication.launchOptions键:任意]?)->Bool
{
self.window=UIWindow(框架:UIScreen.main.bounds)
window!.makeKeyAndVisible()
设testViewController=testViewController()
window!.rootViewController=testViewController
Runner.\u instance.testViewController=testViewController
返回真值
}
func应用程序标识符背景(u应用程序:UIApplication)
{
Runner.\u实例.停止()
}
func applicationIDBecomeActive(u应用程序:UIApplication)
{
Runner.\u instance.start()
}
func应用程序将终止(application:UIApplication)
{
Runner.\u实例.停止()
}
}
类运行程序:NSObject
{
静态let_instance=Runner()
var testViewController:testViewController!
var displayLink:CADisplayLink!
var fps=0
var lastfspcountertime=Date().timeIntervalSince1970
变量计数器=0
func start()
{
如果displayLink==nil
{
displayLink=CADisplayLink(目标:self,选择器:#选择器(Runner.run))
添加(到:RunLoop.main,forMode:RunLoop.Mode.common)
}
}
函数停止()
{
displayLink?.invalidate()
displayLink=nil
}
@objc func run()
{
如果lastFpsCounterTime+1NSAttributedString.Key.paragraphStyle:NSMutableParagraphStyle.default.mutableCopy()作为!NSMutableParagraphStyle
非常奇怪。测量速度的方法是仪器。NSAttributedString.Key.paragraphStyle:NSMutableParagraphStyle.default.mutableCopy()as!NSMutableParagraphStyle
非常奇怪。测量速度的方法是仪器。