ios - 通过自定义协议(protocol)符合协议(protocol) MKAnnotation

标签 ios swift protocols

我想轻松地在 map 上获得 2 种或更多不同的对象类型。 Swift 2.0,我想使用协议(protocol)。

我创建了一个协议(protocol),这些对象也需要遵守。我假设现在任何符合 PinProtocol 的项目在本质上与 MKAnnotation 相同......只是更多!

protocol PinProtocol: MKAnnotation {
    // stuff
}

我有 2 个类(class),员工和客户

两者都符合 PinProtocol(然后还需要符合 MKAnnotation)

我知道这就像我这样设置我的类(class)一样有效,

class Client: NSObject, PinProtocol {
     //var coordinate:CLLocationCoordinate2D // Leave out get doesn't conform to protocol warning as expected
}

因此,这告诉我 PinProtocol 正在按预期工作,因为需要遵守 PinProtocol 的项目也符合 MKAnnotation 协议(protocol)。因为坐标:CLLocationCoordinate2D,是MKAnnotation需要的。

那么为什么我会遇到这个问题

let staffAndClients = [PinProtocol]()

mapView.addAnnotations(staffAndClients) // not allowed!
//mapView.addAnnotations(pins as! [MKAnnotation]) // also not allowed

错误是,无法将类型 [PinProtocol] 的值转换为预期的参数 [MKAnnotation]

PinProtocol 不符合 MKAnnotation,所以应该可以工作。

但是这样做效果很好

let staff = [Staff]()
mapView.addAnnotations(staff) // no problem
let clients = [Client]()
mapView.addAnnotations(clients) // no problem

我可以使用 AnyObject 来解决这个问题,但为什么我不能使用 PinProtocol - 对我来说这似乎更清晰并且是协议(protocol)扩展的整体想法。

感谢您的帮助。

添加...

对于那些面临类似问题的人,我的解决方法是

var pins = [AnyObject]()
mapView.addAnnotations(pins as! [MKAnnotation])

最佳答案

protocol 视为一个模板,您可以使用该模板来制作一些有用的东西,例如学校演示文稿,但您不能将模板本身用于任何演示文稿。

那是因为协议(protocol)缺少方法或属性的实现。要真正获得该特定协议(protocol)的对象,需要实现这些方法。在这种情况下,Java 允许您匿名子类化一个协议(protocol),并强制您实现所需的方法。 (Java叫interface,别和Objective-C的interface搞混了)

与java不同,Swift不支持创建匿名子类,所以任何本身是协议(protocol)的类都不能在Objective-C和Swift中创建对象。实例化它们的唯一方法是让另一个 class(Objective C 中的 interface)符合该协议(protocol)并创建该特定类的实例,StaffClient 在你的情况下。但是,您可以使用协议(protocol)类型的变量,如下所示:

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

staff 在这种情况下是类型为 PinProtocolArray,它不知道有关所创建对象的任何其他信息。

编辑:

我只是正确理解了你的问题。是的,我们可以通过 protocol 名称在 swift 中声明一个类型数组。该数组可以保存符合协议(protocol)的类的对象。您声明数组的语法是正确的。

let staffAndClients = [PinProtocol]()

关于错误 错误是,无法将类型 [PinProtocol] 的值转换为预期的参数 [MKAnnotation] 我查看了文档, 并发现 addAnnotations() 方法采用 AnyObject 数组,如下所示:

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

现在棘手的部分是,MKAnnotation 不是从 AnyObject 继承的,而是从 NSObjectProtocol 继承的,即:

protocol MKAnnotation : NSObjectProtocol

AnyObject 也继承自 NSObjectProtocol,使它成为 MKAnnotation 的兄弟,这就是为什么你会出错,因为你不能传递对象MKAnnotation 的类型,因为它们在其父层次结构中不是 AnyObject

关于ios - 通过自定义协议(protocol)符合协议(protocol) MKAnnotation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32237753/

相关文章:

ios - 如何用 UIScrollView 和 AutoLayout 实现这个简单的屏幕

ios - 保存 Realm 对象时应用程序崩溃... RLMAccessor 将对象设置为 nil

iphone - 找不到协议(protocol)声明 NSObject

ios - swift 。如何在协议(protocol)中从导入的库中声明具有返回类型的函数?

python - 通过 Python 套接字/WebSocket 客户端发送/接收 WebSocket 消息

ios - 防止 Xamarin(/Mono?) 在 iOS 上进行优化

objective-c - 从屏幕外响应丢失动画对象

ios - 在 Swift 中将字符串转换为类类型

swift - OpenGL ES 正交投影矩阵不起作用

arrays - Swift:用于排序路径的排序函数(需要快!)