【问题标题】:Unexpected Non-Void Return Value In Void Function (Swift 2.0)Void 函数中意外的非 Void 返回值 (Swift 2.0)
【发布时间】:2015-11-14 06:20:59
【问题描述】:

我一直在浏览 StackOverflow 问题,试图找出我的代码哪里出了问题,但我似乎无法做到!我正在尝试将我的 Swift 1.2 项目转换为 Swift 2.0,但我的类下载 JSON 数据时遇到问题。

我不断收到错误unexpected non-void return value in void function。

这是我正在使用的代码,有些截断;

...

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()
}

...

也许我忽略了一些简单的事情,但我不确定为什么我的函数会被认为是无效的。任何想法将不胜感激!谢谢!

【问题讨论】:

    标签: swift closures nsurlsession


    【解决方案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()
    }
    

    然后在调用您的函数之前,您应该注册以侦听名称为“minionsFetched”的NSNotification。并且只有在您收到该通知后,您才应该像处理这些奴才一样处理它们。

    【讨论】:

    • 这对我来说很有意义。但是,如果我将return minions 行移到}).resume() 之后,我认为它应该去的地方,我会收到错误Use of unresolved identifier minions。我似乎无法掌握如何解决!
    • 现在对我有意义!谢谢,@Andriy!
    • 感谢@AndriyGordiychuk Gordiychuk 非常重要的一行你有一个问题,因为你的行:return minions 没有从你的函数返回。相反,它从 dataTaskWithRequest 中的完成处理程序返回
    【解决方案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()
    }
    

    【讨论】:

    • 恢复 4 年前的答案的方法,但我们不必关闭 @escaping,因为函数范围将在异步调用之前完成吗?
    猜你喜欢
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多