重叠访问'urlComponents',但修改需要独占访问

Overlapping accesses to 'urlComponents', but modification requires exclusive access

我正在尝试将 Lyft API 与 iOS 11 和 Swift 4 一起使用,但在第二行收到错误消息,即

Overlapping accesses to 'urlComponents', but modification requires exclusive access; consider copying to a local variable.

我不确定这意味着什么,也不知道如何解决。感谢任何帮助,谢谢!

let queryItems = parameters
    .sorted { [=11=].0 < .0 }
    .flatMap { components(forKey: [=11=], value: ) }
var urlComponents = URLComponents(url: mutableURLRequest.url!, resolvingAgainstBaseURL: false)
urlComponents?.queryItems = (urlComponents?.queryItems ?? []) + queryItems //error here

我猜你需要先设置一个局部变量然后再改变它,试试这个:

var urlComponents = URLComponents(url: mutableURLRequest.url!, resolvingAgainstBaseURL: false) 
var localVariable = urlComponents 
urlComponents?.queryItems = (localVariable?.queryItems ?? []) + queryItems  

在这种情况下,问题是对 可选 的重叠访问 所以最简单的解决方案是在 urlComponents 之前解包 改变它的 queryItems:

if var urlComponents = URLComponents(url: mutableURLRequest.url!, resolvingAgainstBaseURL: false) {
    urlComponents.queryItems = (urlComponents.queryItems ?? []) + queryItems
    // ...
}

可能与问题的详细信息没有直接关系,但对于谷歌搜索此错误消息的任何人,请注意该错误也会在尝试使用不明确类型的数据进行操作时发生(目前尚不清楚它是否 class 或操作时的结构)。

可能出现此错误的示例:

protocol: AnItemCapableToShowDetails {
    var isShowingDetails: Bool { get set }
}

class: DataItem, AnItemCapableToShowDetails {
   ...
   var isShowingDetails = false
}

class: SomeClass {
   func showDetails() {
       if let dataItem = itemsArray[index] as? AnItemCapableToShowDetails {
           ...
           dataItem.isShowingDetails = !dataItem.isShowingDetails // <- "Overlapping accesses..." error here
                                                                  // because that protocol might 
                                                                  // potentially be applied to a struct as well
       }
   }
}

可能的解决方法是使其成为仅 class 的协议,以便确保编译器始终使用 class.

进行操作

之前 Swift 4:

protocol: AnItemCapableToShowDetails: class {
    var isShowingDetail: Bool { get set }
}

在 Swift 4 及更高版本中也可用(并且是执行此操作的首选方式):

protocol: AnItemCapableToShowDetails: AnyObject {
    var isShowingDetail: Bool { get set }
}