swift - 重新设计初始化(MKAnnotation)

标签 swift firebase mkannotation

class Point: NSObject, MKAnnotation {
var id: String?
var title: String?
var coordinate: CLLocationCoordinate2D
var subtitle: String?



init(id: String, dictionary: Dictionary<String, AnyObject>){
    self.id = id

    if let title = dictionary["title"] as? String {
        self.title = title
    }

    if let subtitle = dictionary["subtitle"] as? String {
        self.subtitle = subtitle
    }

    if let coords = dictionary["coordinates"] as? [String:[String:Double]] {
        self.coordinate.latitude = coords.values.first!["latitude"]!
        self.coordinate.longitude = coords.values.first!["longitude"]!
    }
   super.init()
}
/*
init(title: String, subtitle: String, coordinate: CLLocationCoordinate2D){
    self.title = title
    self.subtitle = subtitle
    self.coordinate = coordinate

}*/

}

我实现了用于在 map 上创建点的初始值设定项。我必须重新设计 init,因为我使用 Firebase 并且数据库的结果在字典中。 它写道:属性 self.coordinate 未在隐式生成的 super.init 调用中初始化

最佳答案

init(id: String, dictionary: Dictionary<String, AnyObject>){
    self.id = id

    if let title = dictionary["title"] as? String {
        self.title = title
    }

    if let subtitle = dictionary["subtitle"] as? String {
        self.subtitle = subtitle
    }

    if let coords = dictionary["coordinates"] as? [String:[String:Double]] {
        self.coordinate.latitude = coords.values.first!["latitude"]!
        self.coordinate.longitude = coords.values.first!["longitude"]!
    }
    super.init()
}

因此,这里的问题主要在于您只在 if 中初始化 coordinate 属性。由于坐标未标记为可选,因此根据 Swift 初始值设定项的规则,在调用 super.init() 之前应为其指定一个值。

并且因为您仅在 if 内初始化它,所以 if 可能会失败并且您根本不会初始化它。这将使实例处于完全无效的状态,根据 Swift 初始化器的规则,这是不允许的,并且会失败 the first safety check .

Safety check 1

A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.

可以坐标设置为可选实例变量,必须像其他实例变量一样。然而,我认为最有意义的是 idtitle 可能也是非可选的,所有这些属性可能应该是 let 常量。

因此,我将重写您的类和初始化程序:

class Point: NSObject, MKAnnotation {

    let id: String
    let title: String?
    let coordinate: CLLocationCoordinate2D
    let subtitle: String?

    init?(id: String, dictionary: [String: AnyObject]){
        self.id = id

        title = dictionary["title"] as? String

        subtitle = dictionary["subtitle"] as? String

        guard let 
            coordinates = dictionary["coordinates"] as? [String: [String: Double]], 
            latitude = coordinates.values.first?["latitude"],
            longitude = coordinates.values.first?["longitude"] else {

                return nil
        }

        coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)

       super.init()
    }
}

现在您有一个失败的初始化程序。如果字典中的任何值不正确,初始化程序将返回nil。否则,您的值都已正确初始化。

关于swift - 重新设计初始化(MKAnnotation),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37003472/

相关文章:

ios - 后台获取 NSPersistentCloudKitContainer 变化设置通知

ios - 使用 Codable 与 Swift 归档

swift - 在另一个线程上保存 NSManagedContext

ios - 我可以在 GeoFire 查询上应用分页以减少加载时间吗

firebase - Firebase 存储对象的下载 URL 是否永久存在?

ios - 在 Swift 中动画 MapKit 注释坐标变化?

ios - mapView 声明的 Swift 编译器错误

reactjs - 如何在 Firebase firestore 中使用用户 'uid' 创建文档

iphone - 如何更改自定义 MKAnnotationView 的框架位置?

ios - Mapkit 中 NSMutableArray 的多个注释