用存储的属性覆盖

时间:2019-01-29 09:56:15

标签: swift inheritance override member

我以这种方式扩展了MKPointAnnotation类:

class CustomPointAnnotation: MKPointAnnotation{

    let eventID: Int
    let coords: CLLocationCoordinate2D
    var title: String? // error here
    let location:String

    init(eventID:Int, coords:CLLocationCoordinate2D, location:String, title:String?) {

        self.eventID = eventID
        self.coords = coords
        self.title = title
        self.location = location

        super.init()
    }
}

我得到一个错误:

Cannot override with a stored property 'title' 

(我想如果将成员coords重命名为coordinate也会遇到相同的错误)。

因此,我尝试了以下操作:

private var _title:String?

override var title: String? {
        get { return _title }
        set { _title = newValue }
    }

但是,当我在self.title = title的正文中添加init时,我得到:

'self' used in property access 'title' before 'super.init' call

如果我将super.init()移到上方,则会出现两种错误:

  1. Property 'self.eventID' not initialized at super.init call (1 error)
  2. Immutable value 'self.coords' may only be initialized once (repeated for every property)

声明title属性的正确方法是什么?是否有可能覆盖它?我发现了许多与此主题有关的问题,但没有扩展内置类的示例。感谢您的帮助

3 个答案:

答案 0 :(得分:1)

您需要在初始化程序中设置_title,而不是title。由于这是title的私有支持属性,因此,当您首次访问title时,它将具有正确的值,而无需直接设置。

class CustomPointAnnotation: MKPointAnnotation {

    let eventID: Int
    let coords: CLLocationCoordinate2D
    let location:String

    private var _title:String?

    override var title: String? {
        get { return _title }
        set { _title = newValue }
    }

    init(eventID:Int, coords:CLLocationCoordinate2D, location:String, title:String?) {

        self.eventID = eventID
        self.coords = coords
        self._title = title
        self.location = location

        super.init()
    }
}

答案 1 :(得分:1)

您为什么需要再次重新声明var title: String??通过将MKPointAnnotation子类化,您已经可以访问title。 (coords也是如此)。

您可以在super.init()

之后设置标题
init(eventID: Int, coords: CLLocationCoordinate2D, location: String, title: String?) {

        self.eventID = eventID
        self.coords = coords
        self.location = location

        super.init()
        self.title = title
    }

如果出于可读性考虑,要将coordiante重命名为coords,建议使用扩展名:

extension CustomPointAnnotation {
    var coords: CLLocationCoordinate2D {
        get { return coordinate }
        set { coordinate = newValue }
    }
}

并像标题一样在super.init()之后分配它。

答案 2 :(得分:-1)

将注释类设置为

import MapKit


class DGPointAnnotation: NSObject, MKAnnotation {

    var coordinate: CLLocationCoordinate2D
    var title:String?
    var id:Int?
    var sectionId:Int?
    var lat:Double?
    var lng:Double?
    var imageUrl: String?
    var isPartner:Bool?
    var url: String?
    var type:String?
    var subType:Int?


    init(coordinate: CLLocationCoordinate2D) {
        self.coordinate = coordinate
    }
}

在您的视图控制器中,具有MKMapViewDelegate并添加以下代码。

let mapView = MKMapView()
mapView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 400)
mapView.mapType = MKMapType.standard
self.view.addSubview(mapView)
loadMarkers()



func loadMarkers(){
    if let markers = theMarkersObj{
        for marker in markers{
            let latLimitMIN : Double = -90.00
            let latLimitMAX : Double = 90.00
            let longLimitMIN : Double = -180.00
            let longLimitMAX : Double = 180.00

            let lat = marker.lat ?? 0.0
            let lng = marker.lng ?? 0.0

            let centerLocation = CLLocationCoordinate2DMake(CLLocationDegrees(lat), CLLocationDegrees(lng));
            let mynumLat:Double = Double(lat)
            let mynumLong:Double = Double(lng)

            let point = DGPointAnnotation(coordinate: centerLocation)
            point.id = marker.id
            point.sectionId = marker.sectionId
            point.title = marker.title ?? ""
            let mapSpan = MKCoordinateSpanMake(0.5, 0.5)
            let mapRegion = MKCoordinateRegionMake(centerLocation, mapSpan)
            if (!(mynumLat < latLimitMIN) && !(mynumLat > latLimitMAX) && !(mynumLong < longLimitMIN) && !(mynumLong > longLimitMAX)) {
                self.mapView.setRegion(mapRegion, animated: true);
            }
            self.mapView.addAnnotation(point)
            self.mapView.delegate = self


        }
    }
    //print(myMapView?.annotations.count)
}