I want to implement my custom MKAnnotation. I took a look at MKAnnotation protocol(MKAnnotation.h). It's as follow:
我想实现我的自定义MKAnnotation。我看了一下MKAnnotation协议(MKAnnotation.h)。它如下:
//
// MKAnnotation.h
// MapKit
//
// Copyright (c) 2009-2014, Apple Inc. All rights reserved.
//
protocol MKAnnotation : NSObjectProtocol {
// Center latitude and longitude of the annotation view.
// The implementation of this property must be KVO compliant.
var coordinate: CLLocationCoordinate2D { get }
// Title and subtitle for use by selection UI.
@optional var title: String! { get }
@optional var subtitle: String! { get }
// Called as a result of dragging an annotation view.
@optional func setCoordinate(newCoordinate: CLLocationCoordinate2D)
}
Please note the coordinate property (which is a read-only stored property). And here is how I've implemented this protocol:
请注意坐标属性(这是一个只读存储属性)。这是我如何实现这个协议:
class RWDefaultPin: NSObject, MKAnnotation {
var title:String = ""
var subtitle:String = ""
var groupTag:String = ""
var coordinate: CLLocationCoordinate2D { get {
return self.coordinate // this is obviously wrong because property's trying to return itself
} };
init(coordinate:CLLocationCoordinate2D) {
super.init()
self.coordinate = coordinate
}
}
But obviously compiler complaints on my init
method where I'm trying to assign to my coordinate property Cannot assign to 'coordinate' in 'self'
obviously because it's a read-only property.
但显然编译器抱怨我的init方法,我试图分配给我的坐标属性不能分配给'self'中的'coordinate'显然是因为它是一个只读属性。
Previously in Objective-C we could overcome this issue as properties were backed by ivars.
以前在Objective-C中我们可以克服这个问题,因为属性由ivars支持。
I wish there was access modifier in Swift so I could define a private property in my class and set its value on init, and returning its value on get action of coordinate, but there is no such thing!
我希望在Swift中有访问修饰符,所以我可以在我的类中定义一个私有属性并在init上设置它的值,并在get参数的动作上返回它的值,但是没有这样的东西!
I don't quiet know how to fix this issue in Swift, or maybe I need to make it wide open and change my coordinate to be readable/writable?
我不知道如何在Swift中解决这个问题,或者我可能需要将其打开并将我的坐标更改为可读/可写?
2 个解决方案
#1
8
You should be able to just add a setter
to it and store the information in an inner coordinate value. Since you have a getter it is still conforming to the protocol:
您应该只需添加一个setter并将信息存储在内部坐标值中。由于你有一个getter,它仍然符合协议:
var innerCoordinate: CLLocationCoordinate2D
var coordinate: CLLocationCoordinate2D {
get {
return self.innerCoordinate
}
set {
self.innerCoordinate = newValue
}
};
init(coordinate:CLLocationCoordinate2D) {
super.init()
self.innerCoordinate = coordinate
}
This is actually how I implement readonly and private properties (with protocols and the factory pattern). I setup protocols with the public interface and classes with private variables and setters. It is actually super clean way to setup your code (and gets around the lack of protected/private properties in Swift).
这实际上是我如何实现只读和私有属性(使用协议和工厂模式)。我使用公共接口和具有私有变量和setter的类设置协议。它实际上是设置代码的超级干净方式(并且避免了Swift中缺少受保护/私有属性)。
Here is a abstracted example of what I am talking about (if you care):
这是我正在谈论的一个抽象的例子(如果你关心):
// this is your MKAnnotation in this example
protocol SomeProtocol {
var getterProperty: String { get }
var setterProperty: String { set get }
func publicFunction(someStirng: String) -> ();
}
// setup a function that returns a class conforming to your needed protocol
func SomeClassMaker() -> SomeProtocol {
// your internal class that no one can access unless by calling the maker function
class SomeClassInternal: NSObject, SomeProtocol {
// private and no one can get to me!
var innerSetterProperty = "default setter";
var getterProperty = "default getter"
var setterProperty: String {
get {
return self.innerSetterProperty;
}
set {
"hit"
self.innerSetterProperty = newValue
}
}
func publicFunction(someString: String) -> () {
// anyone get me
self.getterProperty = someString;
}
func privateFunction() -> () {
// no one can get me except internal functions
}
}
return SomeClassInternal();
}
// create the class
var classInstance = SomeClassMaker();
// totally fine!
classInstance.setterProperty = "secret string"
// prints "secret string"
classInstance.setterProperty;
// error! no public setter for "getter"
classInstance.getterProperty = "another secret"
classInstance.publicFunction("try secret again")
// prints "try secret again"
let blahed = classInstance.getterProperty
// error!
classInstance.privateFunction()
#2
5
Even though the property is { get }
in the protocol, that is just establishing a minimum criteria. It's perfectly acceptable to define it as read-write:
即使协议中的属性为{get},也就是建立最低标准。将其定义为读写是完全可以接受的:
class MyAnnotation:NSObject, MKAnnotation
{
var coordinate:CLLocationCoordinate2D
init(coordinate:CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
Or, if you really want to keep it as read-only, you can use let:
或者,如果您确实希望将其保持为只读,则可以使用let:
class MyAnnotation:NSObject, MKAnnotation
{
let coordinate:CLLocationCoordinate2D
init(coordinate:CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
#1
8
You should be able to just add a setter
to it and store the information in an inner coordinate value. Since you have a getter it is still conforming to the protocol:
您应该只需添加一个setter并将信息存储在内部坐标值中。由于你有一个getter,它仍然符合协议:
var innerCoordinate: CLLocationCoordinate2D
var coordinate: CLLocationCoordinate2D {
get {
return self.innerCoordinate
}
set {
self.innerCoordinate = newValue
}
};
init(coordinate:CLLocationCoordinate2D) {
super.init()
self.innerCoordinate = coordinate
}
This is actually how I implement readonly and private properties (with protocols and the factory pattern). I setup protocols with the public interface and classes with private variables and setters. It is actually super clean way to setup your code (and gets around the lack of protected/private properties in Swift).
这实际上是我如何实现只读和私有属性(使用协议和工厂模式)。我使用公共接口和具有私有变量和setter的类设置协议。它实际上是设置代码的超级干净方式(并且避免了Swift中缺少受保护/私有属性)。
Here is a abstracted example of what I am talking about (if you care):
这是我正在谈论的一个抽象的例子(如果你关心):
// this is your MKAnnotation in this example
protocol SomeProtocol {
var getterProperty: String { get }
var setterProperty: String { set get }
func publicFunction(someStirng: String) -> ();
}
// setup a function that returns a class conforming to your needed protocol
func SomeClassMaker() -> SomeProtocol {
// your internal class that no one can access unless by calling the maker function
class SomeClassInternal: NSObject, SomeProtocol {
// private and no one can get to me!
var innerSetterProperty = "default setter";
var getterProperty = "default getter"
var setterProperty: String {
get {
return self.innerSetterProperty;
}
set {
"hit"
self.innerSetterProperty = newValue
}
}
func publicFunction(someString: String) -> () {
// anyone get me
self.getterProperty = someString;
}
func privateFunction() -> () {
// no one can get me except internal functions
}
}
return SomeClassInternal();
}
// create the class
var classInstance = SomeClassMaker();
// totally fine!
classInstance.setterProperty = "secret string"
// prints "secret string"
classInstance.setterProperty;
// error! no public setter for "getter"
classInstance.getterProperty = "another secret"
classInstance.publicFunction("try secret again")
// prints "try secret again"
let blahed = classInstance.getterProperty
// error!
classInstance.privateFunction()
#2
5
Even though the property is { get }
in the protocol, that is just establishing a minimum criteria. It's perfectly acceptable to define it as read-write:
即使协议中的属性为{get},也就是建立最低标准。将其定义为读写是完全可以接受的:
class MyAnnotation:NSObject, MKAnnotation
{
var coordinate:CLLocationCoordinate2D
init(coordinate:CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
Or, if you really want to keep it as read-only, you can use let:
或者,如果您确实希望将其保持为只读,则可以使用let:
class MyAnnotation:NSObject, MKAnnotation
{
let coordinate:CLLocationCoordinate2D
init(coordinate:CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}