Подтвердить что ты не робот

Неожиданное невоимое возвращаемое значение в функции Void (Swift 2.0)

Я просматривал вопросы StackOverflow, пытаясь понять, где я ошибаюсь в своем коде, но мне просто не кажется! Я пытаюсь преобразовать мой проект Swift 1.2 в Swift 2.0, и у меня проблема с моим классом, который загружает данные JSON.

Я постоянно получаю сообщение об ошибке Неожиданное неволевое возвращаемое значение в функции void.

Вот код, несколько усеченный, который я использую;

...

class func fetchMinionData() -> [Minion] {

    var myURL = "http://myurl/test.json"

    let dataURL = NSURL(string: myURL)

    let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)

    let session = NSURLSession.sharedSession()

    session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
        let minionJSON = JSON(data!)

        var minions = [Minion]()

        for (_, minionDictionary) in minionJSON {
            minions.append(Minion(minionDetails: minionDictionary))
        }

        return minions
        //THIS IS WHERE THE ERROR OCCURS

    }).resume()
}

...

Возможно, я пропущу что-то простое, но я не уверен, почему моя функция будет считаться недействительной вообще. Любые мысли были бы очень оценены! Спасибо!

4b9b3361

Ответ 1

У вас проблема, потому что ваша строка:

return minions

не возвращается из вашей функции. Вместо этого он возвращается из обработчика завершения в dataTaskWithRequest. И это не должно быть так, потому что это закрытие является функцией void.

Проблема, вызванная тем, что dataTaskWithRequest является асинхронной. Это означает, что он может вернуться позже после выполнения вашей функции.

Итак, вам нужно изменить шаблон дизайна.

Один из способов сделать это будет следующим:

static var minions:[Minion] = [] {
    didSet {
        NSNotificationCenter.defaultCenter().postNotificationName("minionsFetched", object: nil)
   }
}



class func fetchMinionData() {

    var myURL = "http://myurl/test.json"
    let dataURL = NSURL(string: myURL)
    let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)

    let session = NSURLSession.sharedSession()

    session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
        let minionJSON = JSON(data!)

        var minions = [Minion]()

        for (_, minionDictionary) in minionJSON {
            minions.append(Minion(minionDetails: minionDictionary))
        }

        self.minions = minions
        //THIS IS WHERE THE ERROR OCCURS

    }).resume()
}

Затем перед вызовом вашей функции вы должны зарегистрироваться для прослушивания NSNotification с именем "minionsFetched". И только после того, как вы получите это уведомление, вы должны обработать миньонов, как если бы они были извлечены.

Ответ 2

Я исправил мой, создав обработчик завершения. Вы можете сделать это вместо использования уведомлений:

class func fetchMinionData(completionHandler: (minions: [Minion]) -> Void) {

    var myURL = "http://myurl/test.json"

    let dataURL = NSURL(string: myURL)

    let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)

    let session = NSURLSession.sharedSession()

    session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
        let minionJSON = JSON(data!)

        var minions = [Minion]()

        for (_, minionDictionary) in minionJSON {
            minions.append(Minion(minionDetails: minionDictionary))
        }

        completionHandler(minions: minions)
        //THIS IS WHERE YOUR PREVIOUS ERROR OCCURRED

    }).resume()
}