我在ViewDidAppear
中调用动画,稍后在ViewDidAppear
调用一个函数创建几个UIImage对象数组,需要4-5秒才能完成。
同时动画只有0.8秒长,并且有一个完成块:
UIView.animate(withDuration: 0.8, delay: 0.0, options: UIViewAnimationOptions(), animations: {
self.myView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
}, completion: { finished in
self.nextTask()
})
问题是完成块在0.8秒后没有运行 - 它在上一代码完成之后才会运行。
我能做什么除了在DispatchQueue.global(qos: .background).async
的后台线程中运行该代码?或者有没有办法提高后台主题的完成速度?
如果在后台线程中完成,我的动画不会中断,但在后台完成需要更长的时间 - 比如20-30秒而不是4-5秒。
感谢您在此分享的任何帮助!
答案 0 :(得分:2)
我正在调用一个创建多个UIImage对象数组的函数,需要4-5秒才能完成
你绝对不能在主线程上运行它。现代设备上的刷新帧为1/120秒。您不能导致帧丢失。当发生这种情况时,您将阻止用户交互。屏幕将被冻结,Watchdog进程将当场杀死您的应用程序。 (不幸的是,模拟器没有向您显示,也没有在设备上运行Xcode;但是如果您在设备上运行应用程序,请将其停止,然后从设备运行 而不是从Xcode运行,你会明白我的意思。)
问题是完成块在0.8秒后没有运行 - 它在前一代码完成之后才会运行。
正如你所推测的那样,这里有一个重新入侵的问题。您需要离开主线程以允许完成块发生。我真的很惊讶动画甚至开始(是吗?)。当你仍然在主线程上运行代码时,什么都不会发生。
您可以短暂延迟调用import os
global items
import json
def items_get():
items = {
"weapon":{},
"armour":{},
"potion":{},
"misc":{}
}
# Do not use \ as path separators in Windows. Use \\ (\t, \n, \' have speacial meanings)
file_dir = ( os.getcwd() + '\\Code\\items.txt' )
with open( file_dir, 'r') as file_in:
lines = file_in.readlines();
# ['WEAPON 3 sword_of_eventual_obsolescence 6 10 2 0 10\n', 'WEAPON 4 dagger_of_bluntness 2 5 3 1 0\n', 'WEAPON 5 sword_of_extreme_flimsiness 3 8 3 7 0']
for each_line in lines:
# Use strip() to remove any leading/trailing whitespaces (\n, \t, spaces etc.)
line = each_line.strip().split(' ');
if line[0] == "WEAPON":
weapon_id = line[1]
name = line[2]
attack_min = line[3]
attack_max = line[4]
range = line[5]
weight = line[6]
value = line[7]
weapon_data = {
"name": name.replace('_', ' '),
"atk_min": attack_min,
"atk_max": attack_max,
"rng": range,
"wt": weight,
"val": value,
}
items["weapon"][weapon_id] = {}
items["weapon"][weapon_id].update(weapon_data)
return items
# Calling items_get() to get dictionary
items = items_get();
# Pretty printing dictionary using json.dumps()
print(json.dumps(items, indent=4))
以暂时跳出主线程,然后重新输入它,足够长的时间让刷新帧发生,这样系统就可以完成一些工作了。但这只是一种让动画开始的方式。一旦你回到主线程,你就会再次阻止它。
至于速度:{
"weapon": {
"3": {
"name": "sword of eventual obsolescence",
"atk_min": "6",
"atk_max": "10",
"rng": "2",
"wt": "0",
"val": "10"
},
"4": {
"name": "dagger of bluntness",
"atk_min": "2",
"atk_max": "5",
"rng": "3",
"wt": "1",
"val": "0"
},
"5": {
"name": "sword of extreme flimsiness",
"atk_min": "3",
"atk_max": "8",
"rng": "3",
"wt": "7",
"val": "0"
}
},
"armour": {},
"potion": {},
"misc": {}
}
的QOS是最慢的选择,所以你得到了你所要求的。但是,一般情况下,不要使用全局队列;建立自己的队列。我无法想象你在做什么可能需要这么长时间,也许这就是你应该真正要问的问题,但你绝对不能在主线上做到。