我在iOS编程中已经有几天了,所以请耐心等待。我正在尝试使用一些图像矩阵显示UICollectionView。
问题是当从dispatch_async内部初始化UICollectionView时,会显示图像。初始化从viewDidLoad()可以正常工作。 println输出都可以在Xcode控制台中观察到,因此后台进程和主要的后续UI更新应该发生。
我遗漏了其他功能,因为显然它们不是问题(init工作于viewDidLoad)
使用Xcode 6.4。目标是iPhone 5,8.4.1
以下是相关代码:
class MyCollectionViewController: UICollectionViewController, UICollectionViewDataSource, UICollectionViewDelegate {
class MyClass {
var x: Int
var y: Int
var thumbnail: String
init(…) {
}
}
var list = [MyClass]()
override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
// self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
// Do any additional setup after loading the view.
/* uncommenting this works fine
list.append(MyClass(x: 1000, y: 10, thumbnail: “img1.jpg”))
list.append(MyClass(x: 1001, y: 11, thumbnail: “img2.jpg”))
list.append(MyClass(x: 1002, y: 12, thumbnail: “img3.jpg”))
list.append(MyClass(x: 1003, y: 13, thumbnail: “img4.jpg”))
list.append(MyClass(x: 1004, y: 14, thumbnail: “img5.jpg”))
list.append(MyClass(x: 1005, y: 15, thumbnail: “img6.jpg”))
*/
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
println("This is run on the background queue")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
println("This is run on the main queue, after the previous code in outer block")
// This code block below just shows a black screen
self.list.append(MyClass(x: 1000, y: 10, thumbnail: “img1.jpg”))
self.list.append(MyClass(x: 1001, y: 11, thumbnail: “img2.jpg”))
self.list.append(MyClass(x: 1002, y: 12, thumbnail: “img3.jpg”))
self.list.append(MyClass(x: 1003, y: 13, thumbnail: “img4.jpg”))
self.list.append(MyClass(x: 1004, y: 14, thumbnail: “img5.jpg”))
self.list.append(MyClass(x: 1005, y: 15, thumbnail: “img6.jpg”))
})
})
…
}
更新 这是固定代码
class MyCollectionViewController: UICollectionViewController, UICollectionViewDataSource, UICollectionViewDelegate {
class MyClass {
var x: Int
var y: Int
var thumbnail: String
init(…) {
}
}
var list = [MyClass]()
override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
// self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
// Do any additional setup after loading the view.
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
println("This is run on the background queue")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
println("This is run on the main queue, after the previous code in outer block")
self.list.append(MyClass(x: 1000, y: 10, thumbnail: “img1.jpg”))
self.list.append(MyClass(x: 1001, y: 11, thumbnail: “img2.jpg”))
self.list.append(MyClass(x: 1002, y: 12, thumbnail: “img3.jpg”))
self.list.append(MyClass(x: 1003, y: 13, thumbnail: “img4.jpg”))
self.list.append(MyClass(x: 1004, y: 14, thumbnail: “img5.jpg”))
self.list.append(MyClass(x: 1005, y: 15, thumbnail: “img6.jpg”))
// This statement solved the issue
self.collectionView?.reloadData()
})
})
…
}
答案 0 :(得分:2)
UICollectionViewController或UITableViewController尝试在调用viewDidLoad()时调用数据源,因此是同步的。如果某个类需要从服务器获取数据并在良好的异步调用中执行此操作,则意味着数据将在稍后到达并且在调用加载单元的数据源方法之后。
现在要在服务器或异步任务到达后重新加载数据,请调用collectionView的reloadData方法。
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
println("This is run on the background queue")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
println("This is run on the main queue, after the previous code in outer block")
// This code block below just shows a black screen
self.list.append(MyClass(x: 1000, y: 10, thumbnail: “img1.jpg”))
self.list.append(MyClass(x: 1001, y: 11, thumbnail: “img2.jpg”))
self.list.append(MyClass(x: 1002, y: 12, thumbnail: “img3.jpg”))
self.list.append(MyClass(x: 1003, y: 13, thumbnail: “img4.jpg”))
self.list.append(MyClass(x: 1004, y: 14, thumbnail: “img5.jpg”))
self.list.append(MyClass(x: 1005, y: 15, thumbnail: “img6.jpg”))
})
self.collectionView.reloadData() //telling to reload the data once again
})
UICollectionViewController的子类获取了collectionView outlet的默认钩子,我们使用它。
然而,有时我做的是,将一个属性观察者放在数据数组中,然后在那里调用reload。
var list = [MyClass](){
didSet{
//do some work like validation
collectionView.reloadData()
}
}
无论如何,我希望它有所帮助。干杯!