web-dev-qa-db-ja.com

「urlComponents」への重複アクセス、ただし変更には排他的アクセスが必要

IOS 11およびSwift 4でLyft APIを使用しようとしていますが、2行目にエラーが表示されています。

「urlComponents」へのアクセスが重複していますが、変更には排他的アクセスが必要です。ローカル変数へのコピーを検討してください。

これが何を意味するのか、どうすればそれを回避できるのかわかりません。どんな助けもありがたいです、ありがとう!

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

最初にローカル変数に設定してから変更する必要があると思いますが、これを試してください:

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

この場合、問題はoptional、への重複アクセスであるため、urlComponentsを変更する前にqueryItemsのラップを解除するのが最も簡単な解決策です。

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

質問の詳細に直接関係しない場合がありますが、このエラーメッセージをグーグルで検索する場合は、あいまいなタイプのデータを操作しようとするとエラーが発生することに注意してください(操作の時点でクラスか構造体かは不明です) )。

このエラーが表示される場合の例:

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

考えられる修正方法は、クラスのみのプロトコルにすることです。これにより、コンパイラーは常にクラスで操作が行われるようになります。

Before Swift 4:

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

In Swift 4以降も利用可能です(これを行うための好ましい方法です):

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