Swift:自定义属性 setter 因无限循环而崩溃
public protocol RequestType {
var parameters: AnyObject? { get set }
}
public extension RequestType {
public var parameters: AnyObject? {
get { return nil }
set { parameters = newValue }
}
public printParameters() {
print(parameters)
}
}
用法:
class HTTPBinRequest: RequestType { }
let request = HTTPBinRequest()
request.parameters = ["name" : "Rahul"]
request.printParameters()
它崩溃是因为它卡在了递归循环中。
但是当我在类中声明该属性并将 setter 留空时,它就可以正常工作。
class HTTPBinRequest: RequestType {
public var parameters: AnyObject?
}
public extension RequestType {
public var parameters: AnyObject? {
get { return nil }
set {}
}
public printParameters() {
print(parameters)
}
}
let request = HTTPBinRequest()
request.parameters = ["name" : "Rahul"]
谁能建议我如何更好地解决这个问题。
最佳答案
看来您正在尝试在协议(protocol)扩展中创建一个存储属性。你不能那样做。您只能在协议(protocol)扩展中创建计算属性。
这是一个存储属性:
class A {
var value: Int? // Stored property
}
这是一个计算属性:
class B {
var someString: String? // Stored property
var value: Int? { // Computed property
get { return Int(someString) }
set { someString = "\(newValue)" }
}
}
计算属性无法自行设置 - 如果您尝试这样做,它会创建您正在经历的递归循环。但它可以做其他事情,比如设置类的其他存储属性,如上面的示例中接受 Int
作为新值,然后将其存储为 String
. Int
值本身从不存储。当您检索 Int
值时,它会在每次访问时从 someString
计算它。
如果您尝试将此作为协议(protocol)来执行,则可以将计算属性放入协议(protocol)中,而不是存储属性:
protocol BProtocol {
var someString: String? { get set }
var value: Int? { get set }
}
extenstion BProtocol {
var value: Int? {
get { return Int(someString) }
set { someString = "\(newValue)" }
}
}
但是你仍然需要在类中定义存储属性:
class B: BProtocol {
var someString: String?
}
但是您不需要定义 value
属性。 B 类
将从 BProtocol
扩展继承。
所以对你的问题的简短回答是,在你的类中创建存储的属性,而不是在协议(protocol)扩展中。
编辑:
根据评论,您可能需要使用双层协议(protocol)。第一个协议(protocol)规定了不使用 parameters
属性的对象的要求:
protocol BaseProtocol {
var someStuff: String? { get set }
}
protocol BaseProtocolWithParameters: BaseProtocol {
var parameters: AnyObject? { get set }
}
我之所以这么说,是因为通常来说,如果协议(protocol)的要求是要求用户创建从未使用过的属性,那这种设计是糟糕的设计。如果某些对象永远不会使用 parameters
,则不应要求这些对象遵守它们不需要的协议(protocol)要求。它们可以符合 BaseProtocol
。真正需要使用parameters
的对象可以遵循继承自BaseProtocol
的BaseProtocolWithParameters
。
关于ios - swift 协议(protocol) : Custom Property Setter Crash because of Recursive loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36267322/