iOS上的Swift:全局队列上的任务将第二个任务添加到主队列中,以显示不显示的UIImageView



我正在尝试显示一个在屏幕上移动的UIImageView图标。但图标并没有显示。

  1. viewDidLoad执行以下操作:DispatchQueue.global((.async{app_class.run_app((}

  2. run_app从数组sim_locations_track_array中获取下一个XY位置,转换到屏幕位置,然后显示UIImageView图标:DispatchQueue.main.sync{…CGRect…}

但什么都不显示。

这是我的密码。。。

import UIKit
class ViewController: UIViewController {
@IBOutlet weak var app_title: UILabel!
static let wrist_band_UIImageView: UIImageView = {
let theImageView = UIImageView()
theImageView.image = UIImage( systemName: "applewatch" )
theImageView.translatesAutoresizingMaskIntoConstraints = false //You need to call this property so the image is added to your view
return theImageView
}()
override func viewDidLoad()         
{
print("viewDidLoad...")
super.viewDidLoad()
view.addSubview( ViewController.wrist_band_UIImageView )
DispatchQueue.global().async{ 
app_class.run_app()
}
}
}


class app_class
{
// X, Y, Z, timestamp in seconds
static let sim_locations_track_Array: [Int]  = [     0, 0, 0,   3,
0, 1, 0,   3,
0, 2, 0,   3,
0, 3, 0,   3,
0, 0, 0,   -999 ]
static let items_per_time = 4

static var screen_width = 100
static var screen_height = 100
static var screen_offset_x = 400
static var screen_offset_y = 400
static var screen_location_x = 0

// Run app that animates track of user following sim locations track.
static func run_app()
{
var xcoord = 0
var ycoord = 0
var delay_time_seconds = 1.0
var locations_index = 0
var map_multiplier = 10
var loop = 0
// Loop for each location:
while true
{
//  Read XY from locations track:
var board_x = sim_locations_track_Array[ locations_index * items_per_time ]
var board_y = sim_locations_track_Array[ locations_index * items_per_time + 1 ]
var relative_timestamp_seconds = sim_locations_track_Array[ locations_index * items_per_time + 3 ]
var screen_y = screen_height - board_x
var screen_x = screen_width / 2 + board_y
// Not end of data?
if  relative_timestamp_seconds > 0
{
DispatchQueue.main.async{
ViewController.wrist_band_UIImageView.frame = CGRect(   x: screen_x * map_multiplier, 
                  y: screen_y * map_multiplier,
                  width: screen_width, 
                  height: screen_height)
}
sleep( UInt32( relative_timestamp_seconds ))
locations_index += 1
}
else          // End of locations track data?
{
locations_index = 0
}
}
}
}        // end of app_class

您不应该在main线程上调用sync,这会导致死锁,请改用async

DispatchQueue.main.sync{
ViewController.wrist_band_UIImageView.frame = CGRect(   x: screen_x * map_multiplier, 
                  y: screen_y * map_multiplier,
                  width: screen_width, 
                  height: screen_height)
}

sync将把工作分派到另一个队列,但当前队列将等待工作完成。简而言之,sync会阻塞当前队列。同步(执行:(文档

您的代码实际上什么都不做。您在app_class类上使用一个静态方法,该方法获取ViewController类的静态计算属性(wrist_band_UIImageView(,更新新创建的计算UIImageView的帧,然后。。。将图像视图放置在地板上。

ViewController.wrist_band_UIImageView获取值的结果是新创建的UIImageView,它不属于任何视图层次结构。除非将它安装到某个视图层次结构中,否则它不会执行任何操作。

另一件事。此代码:

DispatchQueue.global().sync() {
sleep( UInt32( relative_timestamp_seconds ))
}

毫无意义。您正在从后台线程运行它。然后调用另一个后台队列,并告诉它同步。。。进入睡眠状态,持续几秒钟。这有什么意义?如果希望当前后台作业处于睡眠状态,只需直接调用sleep即可。将一个呼叫分配到全局同步队列,而您只是告诉它休眠,这是荒谬的。

你应该退一步,解释一下你想要实现的目标。

最新更新