Swift /将对象添加到NSMutable Array

时间:2017-03-27 16:56:02

标签: arrays swift

我是Swift的新手,我很难理解为什么这不起作用 - 我已经通过stackoverflow和我的变量"集合"上的示例尝试了很多不同的组合。仍然是空的(见最后一行),所以我猜测我错过了一个小的(但很重要的)细节。感谢任何帮助!

class CollectionsViewController: UITableViewController {

    var collections = NSMutableArray()


    override func viewDidLoad() {
        super.viewDidLoad()

        SDK.sharedInstance()
            .getAuthenticatedUserBoards(withFields: ["id", "name","url","description","image"],
                success: { data in
                    guard let myData = data?.parsedJSONDictionary["data"] as? [[String: Any]]

                    else {
                        return
                    }

                    for item in myData {
                        self.collections.add(item)
                    }
            }, andFailure: nil)

            print("collections.....\(collections)") 
            //Output: collections.....() 
    }

2 个答案:

答案 0 :(得分:1)

加载数据是异步的。由于您的目标是在加载数据后加载表格视图,因此您需要在reloadData块末尾的表格视图上调用success。但是必须在主队列上进行UI调用,因此您应该使用DispatchQueue来执行此操作。

以下是您的需求:

override func viewDidLoad() {
    super.viewDidLoad()

    SDK.sharedInstance()
        .getAuthenticatedUserBoards(withFields: ["id", "name","url","description","image"],
            success: { data in
                guard let myData = data?.parsedJSONDictionary["data"] as? [[String: Any]]

                else {
                    return
                }

                for item in myData {
                    self.collections.add(item)
                }
                print("collections.....\(collections)") 

                DispatchQueue.main.async {
                    tableView.reloadData()
                }
        }, andFailure: nil)
}

由于您当前正在后台更新self.collections,因此主队列上的UI很可能会看到部分最新的数据集。所以我建议进一步改变:

override func viewDidLoad() {
    super.viewDidLoad()

    SDK.sharedInstance()
        .getAuthenticatedUserBoards(withFields: ["id", "name","url","description","image"],
            success: { data in
                guard let myData = data?.parsedJSONDictionary["data"] as? [[String: Any]]

                else {
                    return
                }

                var list = NSMutableArray()
                for item in myData {
                    list.add(item)
                }

                DispatchQueue.main.async {
                    self.collections = list
                    print("collections.....\(collections)") 
                    tableView.reloadData()
                }
        }, andFailure: nil)
}

这确保主collections属性仅在主线程上更新。

我还建议您使用特定类型的Swift数组,而不是使用NSMutableArray

答案 1 :(得分:0)

我假设getAuthenticatedUserBoards正在对API进行某种异步调用。由于我们不确定该调用将持续多长时间,因此任务将放在后台线程上,而应用程序的其余任务将继续在主线程上运行。您的print语句是在后台进行API调用时将运行的任务之一。实质上,print语句在getAuthenticatedUserBoards内部的任何内容完成之前执行。

应该在for循环之后和闭包结束之前直接打印集合列表。您可以通过在函数中的各个不同位置放置print语句来验证完成不同任务的顺序 - 您应该能够看到当前的print语句将在您放置在闭包内的任何其他语句之前打印。 / p>