代码之家  ›  专栏  ›  技术社区  ›  forrest

如何从非隔离上下文中引用“共享”静态属性?

  •  0
  • forrest  · 技术社区  · 1 年前

    我正在Xcode 15.4中开发一个地图应用程序。

    一切正常,除非我引用 @MainActor类位置管理器{} 私有var定位管理器

    我得到以下错误:

    无法引用主参与者隔离的静态属性“shared” 来自非孤立的环境;这是Swift 6中的一个错误

    我是Swift 6的新手,可能需要一些指导来解决这个问题。

    以下是代码:

    import SwiftUI
    import MapKit
    
    @MainActor class LocationManager {
        static let shared = LocationManager()
        let manager: CLLocationManager
        
        init() {
            self.manager = CLLocationManager()
            if self.manager.authorizationStatus == .notDetermined {
                self.manager.requestWhenInUseAuthorization()
            }
        }
    }
    
    extension CLLocationCoordinate2D {
        static var notreDam: CLLocationCoordinate2D {
            CLLocationCoordinate2D(latitude: 48.853218898078126, longitude:2.349977679044624)
        }
        
        static var saintGermain: CLLocationCoordinate2D {
            CLLocationCoordinate2D(latitude: 48.854184067183304, longitude:2.334469956279526)
        }
        
        static var saintDenis: CLLocationCoordinate2D {
            CLLocationCoordinate2D(latitude: 48.93693647702151, longitude:2.3565013545150872)
        }
        
        static var saintEustach: CLLocationCoordinate2D {
            CLLocationCoordinate2D(latitude: 48.86350319977858, longitude:2.345539521410205)
        }
        
        static var saintEtienne: CLLocationCoordinate2D {
            CLLocationCoordinate2D(latitude: 48.846708620929796, longitude: 2.34847593490404)
        }
        
    }
    
    enum MapOptions: String, Identifiable, CaseIterable {
        case standard
        case hybrid
        case imagery
        
        var id: String {
            self.rawValue
        }
        
        var mapStyle: MapStyle {
            switch self {
            case .standard:
                return .standard
            case .hybrid:
                return .hybrid
            case .imagery:
                return .imagery
            }
        }
    }
    
    struct ContentView: View {
        
        private var locationManager = LocationManager.shared
        @State private var selectedMapOption: MapOptions = .standard
        
        var body: some View {
            ZStack(alignment: .top) {
                Map {
                    Annotation("Notre Dame", coordinate: .notreDam) {
                        Image(systemName: "house.circle.fill")
                            .padding(4)
                            .background(.red)
                            .foregroundColor(.white)
                            .cornerRadius(20.0)
                    }
                    
                    Annotation("Saint Germain", coordinate: .saintGermain) {
                        Image(systemName: "house.circle.fill")
                            .padding(4)
                            .background(.red)
                            .foregroundColor(.white)
                            .cornerRadius(20.0)
                    }
                    
                    Annotation("Saint Denis", coordinate: .saintDenis) {
                        Image(systemName: "house.circle.fill")
                            .padding(4)
                            .background(.red)
                            .foregroundColor(.white)
                            .cornerRadius(20.0)
                    }
                    
                    Annotation("Saint Eustache", coordinate: .saintEustach) {
                        Image(systemName: "house.circle.fill")
                            .padding(4)
                            .background(.red)
                            .foregroundColor(.white)
                            .cornerRadius(20.0)
                    }
                    
                    Annotation("Saint Etienne", coordinate: .saintEtienne) {
                        Image(systemName: "house.circle.fill")
                            .padding(4)
                            .background(.red)
                            .foregroundColor(.white)
                            .cornerRadius(20.0)
                    }
                    
                    UserAnnotation()
                    
                }.mapStyle(selectedMapOption.mapStyle)
                Picker("Map Styles", selection: $selectedMapOption) {
                    ForEach(MapOptions.allCases) { mapOption in
                        Text(mapOption.rawValue.capitalized).tag(mapOption)
                    }
                }.pickerStyle(.segmented)
                    .background(.white)
                    .padding()
            }
        }
    }
    
    #Preview {
        ContentView()
    }
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   yo1995    1 年前

    一个简单的方法是注释 ContentView 具有 @MainActor -因此,使用共享实例的上下文变得与主要参与者隔离。

    当你转到Xcode 16和Swift 6时,View会被标记为 @主要演员 所以到那时,这个警告就会消失。

    请参阅 What’s new in SwiftUI - WWDC 2024 大约17:30。

    推荐文章