在Swift中初始化期间设置只读存储属性的值
我想实现我的自定义注释。我看了一下MKAnnotation协议(MKAnnotation.h)。 具体如下:在Swift中初始化期间设置只读存储属性的值,swift,Swift,我想实现我的自定义注释。我看了一下MKAnnotation协议(MKAnnotation.h)。 具体如下: // // MKAnnotation.h // MapKit // // Copyright (c) 2009-2014, Apple Inc. All rights reserved. // protocol MKAnnotation : NSObjectProtocol { // Center latitude and longitude of the annota
//
// 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)
}
请注意坐标属性(它是只读存储属性)。
下面是我如何实现这个协议的:
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
}
}
var innerCoordinate: CLLocationCoordinate2D
var coordinate: CLLocationCoordinate2D {
get {
return self.innerCoordinate
}
set {
self.innerCoordinate = newValue
}
};
init(coordinate:CLLocationCoordinate2D) {
super.init()
self.innerCoordinate = coordinate
}
但显然,编译器对我试图分配给坐标属性的init
方法表示不满,因为它是只读属性,所以无法分配给'self'
中的'coordinate'
在之前的Objective-C中,我们可以克服这个问题,因为房地产由IVAR支持
我希望Swift中有一个访问修饰符,这样我就可以在类中定义一个私有属性,并在init上设置它的值,在坐标的get操作上返回它的值,但是没有这样的事情
我不知道如何在Swift中解决此问题,或者我需要将其完全打开并更改坐标以使其可读/写 您应该能够向其添加一个
设置器
,并将信息存储在内部坐标值中。因为您有一个getter,所以它仍然符合协议:
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
}
}
var innerCoordinate: CLLocationCoordinate2D
var coordinate: CLLocationCoordinate2D {
get {
return self.innerCoordinate
}
set {
self.innerCoordinate = newValue
}
};
init(coordinate:CLLocationCoordinate2D) {
super.init()
self.innerCoordinate = coordinate
}
这实际上就是我实现只读和私有属性(使用协议和工厂模式)的方式。我使用公共接口设置协议,使用私有变量和setter设置类。它实际上是一种超级干净的代码设置方式(并且可以避免Swift中缺少受保护/私有属性)
下面是我所说内容的一个抽象示例(如果您愿意):
即使协议中的属性是
{get}
,这只是建立了一个最低标准。完全可以将其定义为读写:
class MyAnnotation:NSObject, MKAnnotation
{
var coordinate:CLLocationCoordinate2D
init(coordinate:CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
或者,如果您确实希望将其保持为只读,可以使用let:
class MyAnnotation:NSObject, MKAnnotation
{
let coordinate:CLLocationCoordinate2D
init(coordinate:CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
您是否尝试创建真正私有的
坐标属性?一个可以在初始化期间设置的属性,它是公共坐标
getter返回的值?为什么不向它添加一个集合
?@Firo,这个属性在Objective-C中是只读的,如果您注意到,apple在MKAnnotation.h中将其定义为只读(变量坐标:CLLocationCoordinate2D{get})@CjCoax并不意味着你的类可以给它一个setter。这只意味着协议不会强制设置器,它会阻止任何不知道实际类的人设置属性。@CjCoax,我犯了一个错误。显然你不能做我建议的事。在setter中设置属性实际上会运行到一个无限循环中(因为现在设置了属性,所以它会再次调用setter)。很抱歉请参见“编辑”。@JamieForrest如果您有权访问该类,则会这样做,但如果您通过协议访问设计代码,则访问器类只能获得它。这是拥有私有变量和函数的好方法。它还允许进行一些清洁单元测试。让我用一个彻底的例子来完善我的答案。。。给我一个sec@JamieForrest,我用一个简短的例子编辑了答案。我在最初的回答中也犯了一个错误。