如何在Swift 4.2x中访问/操纵作为函数中的参数传递的可变数组?

时间:2018-12-23 06:40:53

标签: arrays swift swift4.2

我在下面有以下代码:

var rootTasks: [Task]?

func loadRootTasks() {
    rootTasks == nil ? rootTasks = [Task]() : rootTasks?.removeAll() // removeAll() works here
    TasksManager.loadTasks(parentTaskIDString: "0", tasks: &rootTasks!)
}

static func loadTasks(parentTaskIDString: String, tasks: inout [Task]) {

    let urlString = Config.httpsProtocol + "://" + Config.server + Config.portString + "/" + TasksManager.getTasksEndpoint + "/" + parentTaskIDString
    let url = URL(string: urlString)
    var urlRequest = URLRequest(url: url!)
    urlRequest.setValue(AccountsManager.sharedInstance.securityAccessToken, forHTTPHeaderField: "Authorization")

    let defaultSession = URLSession(configuration: .default)
    let getTasksTask = defaultSession.dataTask(with: urlRequest, completionHandler: { (data, response, error) in

        guard (response as? HTTPURLResponse)?.statusCode == 200 else {
            print("GetTasks response status code != 200")
            return
        }

        guard error == nil else {
            print("GetTasks error")
            return
        }

        guard let jsonData = data else {
            print("GetTasks did not receive JSON data")
            return
        }

        do {
            // PROBLEM is here:
            // compiler flags "Escaping closures can only capture inout parameters explicitly by value"
            tasks.removeAll() // removeAll() does not work here
            // same error here
            tasks = try JSONDecoder().decode([Task].self, from: jsonData)
            NotificationCenter.default.post(name: .rootTasksRefreshed, object: nil, userInfo: nil)
        }
        catch {
            print("GetTasks JSON parsing exception")
        }
    })

    getTasksTask.resume()
}

问题出在“ // PROBLEM ...”行中。编译器标记“转义的闭包只能按值显式捕获inout参数”错误。

函数“ loadTasks”是一个静态方法,由“ loadRootTasks”调用。它需要传递一个作为成员变量的“任务”数组,并且需要在异步方法dataTask()运行后从静态方法内部进行修改。

如何解决问题以便能够“ tasks.removeAll()”等?

我还阅读了其他文章,但没有针对Swift 4.2的文章。我需要专门针对Swift 4.2的帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

您无法在异步代码中操纵inout参数。

在这种情况下,没有必要这样做。根本不要将rootTasks传递给您的loadTasks方法。首先,使您的loadTasks方法成为实例方法,而不是静态方法。现在,您的loadTasks方法可以直接参见 rootTasks。这样就可以直接更改它!

因此,在这一点上,不必说

        tasks.removeAll() // removeAll() does not work here

只要说

        self.rootTasks.removeAll()

以此类推。

(但是,异步代码可能应该注意只在主线程上触摸self.rootTasks。)

如果您不想这样做(也就是说,如果您坚持将loadTasks保留为静态方法),则必须以常规方式进行:loadTasks必须然后将调用的完成处理程序,作为将数组异步传递回原始调用方的一种方式。