web-dev-qa-db-fra.com

Chevauchement des accès à «urlComponents», mais la modification nécessite un accès exclusif

J'essaie d'utiliser l'API Lyft avec iOS 11 et Swift 4, et je reçois une erreur sur la deuxième ligne, qui est

Chevauchement des accès aux "urlComponents", mais la modification nécessite un accès exclusif; envisagez de copier dans une variable locale.

Je ne sais pas ce que cela signifie et comment je peux y remédier. Toute aide est la bienvenue, merci!

let queryItems = parameters
    .sorted { $0.0 < $1.0 }
    .flatMap { components(forKey: $0, value: $1) }
var urlComponents = URLComponents(url: mutableURLRequest.url!, resolvingAgainstBaseURL: false)
urlComponents?.queryItems = (urlComponents?.queryItems ?? []) + queryItems //error here
13
John Harding II

Je suppose que vous devez d'abord définir une variable locale, puis la modifier, essayez ceci:

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

Dans ce cas, le problème est l'accès superposé à un facultatif donc la solution la plus simple serait de déballer urlComponents avant de muter son queryItems:

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

Peut ne pas être directement lié aux détails de la question, mais pour quiconque google ce message d'erreur, sachez que l'erreur se produit également lors d'une tentative de manipulation avec des données de type ambigu (il n'est pas clair s'il s'agit d'une classe ou d'une structure au moment de la manipulation). ).

Exemple lorsque cette erreur peut apparaître:

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

Le correctif possible consiste à en faire un protocole de classe uniquement, afin que le compilateur soit assuré que les manipulations sont toujours effectuées avec une classe.

Pour avant Swift 4:

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

Dans Swift 4 et versions ultérieures également disponibles (et est une façon préférée de le faire)):

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