Conform to Protocol MKAnnotation via Custom Protocol

后端 未结 2 1741
星月不相逢
星月不相逢 2021-01-14 05:25

I want to get 2 or more different object types on a map easily. Swift 2.0, I wanted to use Protocols.

I created a protocol that these object need to conform too. I a

相关标签:
2条回答
  • 2021-01-14 05:59

    Consider protocol as a template, you can use that template to make something useful like school presentation, but you cannot use the template itself for any presentation.

    That's because protocol lacks the implementation of the methods or properties. To really get an object of that particular protocol, these methods needs to be implemented. Java in that case lets you anonymously sub-class a protocol, and forces you to implement the required methods. (Java calls it interface, don't confuse it Objective-C interface)

    Unlike java, Swift doesn't support creating anonymous sub-classes, so any class that itself is a protocol cannot create objects in Objective-C and Swift. The only way of instantiating them is getting another class (interface in Objective C) conform that protocol and create instance of that particular class, Staff and Client in your case. However you can have a variable with the type of protocol as follow:

    let staff = [PinProtocol]() //PinProtocol type array. can hold any type of objects that conform to this protocol
    

    staff in this case is Array of type PinProtocol, it doesn't know any other info regarding the object created.

    Edit:

    I just understood your question correctly. Yes, we can declare an array of type in swift by protocol names. And that array can hold objects of the classes that conform to the protocol. Your syntax of declaring array is correct.

    let staffAndClients = [PinProtocol]()
    

    Regarding the error The error is, cannot convert value of type [PinProtocol] to to expected argument [MKAnnotation] I looked into documentations, and found out that the method addAnnotations() takes array of AnyObject as follow:

    func addAnnotations(annotations: [AnyObject]!) //in MKMapView 
    

    Now the tricky part is, MKAnnotation doesn't inherit from AnyObject, but instead from NSObjectProtocol ie:

    protocol MKAnnotation : NSObjectProtocol
    

    Whereas AnyObject also inherit from NSObjectProtocol, making it sibling of MKAnnotation that's why you're getting error, because you cannot pass object with types of MKAnnotation, because they're not AnyObject in their parent hierarchy.

    0 讨论(0)
  • 2021-01-14 06:09

    After dealing with the hassle of MapViewController's data source being

    var pins = [AnyObject]()
    

    I came to the realisation that I could easily avoid all the associated issues of type checking and use the preferred array of PinProtocols

    var pins = [PinProtocol]()
    

    The workaround was simply

    func addToMap() {
        let mappingPins = pins.map{ $0 as AnyObject }
        mapView.addAnnotations(mappingPins as! [MKAnnotation])
        mapView.showAnnotations(mappingPins as! [MKAnnotation], animated: true)
    }
    
    0 讨论(0)
提交回复
热议问题