【问题标题】:Mutating function inside structure结构内部的变异函数
【发布时间】:2018-10-22 03:47:47
【问题描述】:

我使用的是 Swift 4,我有一个使用默认值初始化的结构。 我在里面创建了一个函数,它应该读取 JSON 并用它得到的内容更改这些默认值,但它似乎不起作用。

错误:闭包无法隐式捕获变异的 self 参数

代码:

struct Workspace: Decodable {
    var guid: String
    var name: String

private enum CodingKeys : String, CodingKey {
    case guid = "guid"
    case name = "name"
}

init(){
    self.guid = "blbl"
    self.name = "oops"
}

mutating func getUserWorkspace(base: String, completed: @escaping () -> ()){
    let url = URL(string: "some url")!
    var request = URLRequest(url: url)

    request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    URLSession.shared.dataTask(with: request){ (data, response, error) in
        if error == nil {
            do {
                let res: Workspace = try JSONDecoder().decode(Workspace.self, from: data!)
                self.guid = res.guid  //Error here
                self.name = res.name  //Error here
                DispatchQueue.main.async {
                    completed()
                }
            }catch {
                print ("JSON error")
            }
        }
    }.resume()
}

我把 let 改成了 var,但我想还是有什么我不明白的地方..

【问题讨论】:

  • 如果 Swift 允许您捕获变异的 self 参数,那么它可以有效地让您使用值类型(例如结构的实例)作为引用类型。

标签: swift structure mutating-function


【解决方案1】:

我实际上发现了问题.. 它非常愚蠢.. 我只需要更改函数的“已完成”部分,如下所示:

 mutating func getUserWorkspace(base: String, completed: @escaping (_ arr:[Workspace]?) -> ()){
    let url = URL(string: "SOME URL")!
    var request = URLRequest(url: url)

    request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    URLSession.shared.dataTask(with: request){ (data, response, error) in
        if error == nil {
            do {
                let rep = try JSONDecoder().decode([Workspace].self, from: data!)
                DispatchQueue.main.async {
                    completed(rep)
                }
            }catch {
                print(error)
            }
        }
    }.resume()
}

【讨论】:

    【解决方案2】:

    我建议你使用 class 而不是 struct。无论如何,如果你喜欢使用你的代码,那么在你的变异方法中捕获 self,如下所示:

    mutating func getUserWorkspace(base: String, completed: @escaping () -> ()){
            let url = URL(string: "some url")!
            var request = URLRequest(url: url)
            var myself = self
    
            request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
            request.addValue("application/json", forHTTPHeaderField: "Accept")
    
            URLSession.shared.dataTask(with: request){ (data, response, error) in
                if error == nil {
                    do {
                        let res: Workspace = try JSONDecoder().decode(Workspace.self, from: data!)
                        myself.guid = res.guid  //Error here
                        myself.name = res.name  //Error here
                        DispatchQueue.main.async {
                            completed()
                        }
                    }catch {
                        print ("JSON error")
                    }
                }
                }.resume()
      }
    

    【讨论】:

      【解决方案3】:
      //Try this one and let me know
      struct Workspace: Decodable {
          static var shared = Workspace()
          var guid: String
          var name: String
      
          private enum CodingKeys : String, CodingKey {
              case guid = "guid"
              case name = "name"
          }
      
          init(){
              self.guid = "blbl"
              self.name = "oops"
          }
      
          mutating func getUserWorkspace(base: String, completed: @escaping () -> ()){
              let url = URL(string: "some url")!
              var request = URLRequest(url: url)
      
              request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
              request.addValue("application/json", forHTTPHeaderField: "Accept")
      
              URLSession.shared.dataTask(with: request){ (data, response, error) in
                  if error == nil {
                      do {
                          let res: Workspace = try JSONDecoder().decode(Workspace.self, from: data!)
                          Workspace.shared.guid = res.guid  //Error here
                          Workspace.shared.name = res.name  //Error here
                          DispatchQueue.main.async {
                              completed()
                          }
                      }catch {
                          print ("JSON error")
                      }
                  }
                  }.resume()
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-01-12
        • 2013-10-27
        • 1970-01-01
        • 1970-01-01
        • 2021-09-05
        • 1970-01-01
        • 2014-10-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多