При извлечении данных из оператора завершения переменные возвращают пустое значение.

Я новичок в программировании iOS, и у меня возникают проблемы при использовании переменных из оператора завершения. Я включил приведенный ниже код, я не уверен, почему, когда я сохраняю переменные завершения в массиве dataType, кажется, что возвращаются только пустые строки.

Примечание. Данные завершения вызываются в функции loadSampleStockData, и позже предполагается, что они будут возвращены в ячейки в func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

Спасибо за любую помощь, которая может быть предоставлена!

import UIKit

class dashboardViewController: DefaultViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var balanceLabel: UILabel!

    var stocks = [stockData]()
    let stock = stockinfo()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.reloadData()
        loadSampleStockData()
        user.newUser() // Move to login function when login and registration is implemented

        //Sets the Balance Label on Dashboard
        balanceLabel.text = "$" + String(format: "%.2f", user.getBalance())
    }

    func loadSampleStockData () {

        var stock1: stockData = stockData(name: "", askPrice: "", percentageChange: "", stockTicker: "")
        var stock2: stockData = stockData(name: "", askPrice: "", percentageChange: "", stockTicker: "")
        var stock3: stockData = stockData(name: "", askPrice: "", percentageChange: "", stockTicker: "")

        stock.getInfo("FB") {(name, price, change) in dispatch_async(dispatch_get_main_queue(),{
            stock1 = stockData(name: name, askPrice: price, percentageChange: change, stockTicker: "FB")
            stocks.append(stock1)
        })
        }

        stock.getInfo("MSFT") {(name, price, change) in dispatch_async(dispatch_get_main_queue(),{
            stock2 = stockData(name: name, askPrice: price, percentageChange: change, stockTicker: "MSFT")
            stocks.append(stock2)
        })
        }

        stock.getInfo("APPL") {(name, price, change) in dispatch_async(dispatch_get_main_queue(),{
            stock3 = stockData(name: name, askPrice: price, percentageChange: change, stockTicker: "APPL")
            stocks.append(stock3)
        })
        }
        print(stocks.count)
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return stocks.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cellIdentifier = "stockViewCell"

        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! stockTableViewCell

        let stock = stocks[indexPath.row]

        cell.stockName.text = stock.name
        cell.stockPercentage.text = stock.percentageChange
        cell.stockDollarChange.text = stock.askPrice
        cell.stockTicker.text = stock.stockTicker

        return cell
    }
}

person Mark Gong-Guy    schedule 05.07.2016    source источник


Ответы (1)


Потому что stocks += [stock1, stock2, stock3] происходит до того, как ваши асинхронные вызовы установят stock1...3 на что-либо.

Создание stocks должно выполняться в обработчике завершения.

person Alexander    schedule 05.07.2016
comment
Спасибо за ответ, вопрос может быть невежественным, но если я инициирую акции в обработчике завершения, не смогу ли я вызвать их в другом обработчике завершения и, следовательно, в других функциях из-за области действия переменной? Возможно, я неправильно понял, не могли бы вы предоставить фрагмент кода? Спасибо за вашу помощь - person Mark Gong-Guy; 05.07.2016
comment
Вам понадобится общее состояние, такое как указанная здесь переменная экземпляра. Каждый обработчик завершения будет добавлять в массив асинхронно, а основной поток будет ждать, пока все они не будут выполнены. - person Alexander; 05.07.2016
comment
Большое спасибо за ваше терпение и за то, что нашли время помочь мне в этом. Я попытался добавить данные к «запасам» в обработчике завершения. Как я могу передать «запасы» в обработчики завершения. Я внес свои изменения выше, ошибаюсь ли я, и если да, не могли бы вы предоставить мне фрагмент кода. Большое спасибо за вашу помощь, я продолжу гуглить и читать документацию - person Mark Gong-Guy; 05.07.2016
comment
Вы не передаете stocks, замыкание автоматически захватит ссылку на него. Я не могу предложить никаких фрагментов кода, так как я еще не работал с многопоточным Swift. Вам нужно поместить блокировку / семафор / мьютекс вокруг инструкции .append(), чтобы предотвратить состояние гонки. - person Alexander; 05.07.2016