Reputation: 18308
I come from Java world. Now I am programming in Swift 4.
I would like to implement abstract class in Swift, I know in Swift there is no such concept of abstract class. But I know we could mimic this concept in Swift by using protocol. For example this is what I tried:
// With protocol, I can define functions that concrete class have to implement
protocol ProductProvider {
func getProductNumber() -> Int
}
// with protocol extension, I can define shared (computed) properties and functions among concrete classes that comply with this protocol
extension ProductProvider {
var maxProductCount: Int {
return 10
}
}
But now, I would like to have a shared variable that could be set & get ("shared" means to be shared with classes that comply with this protocol):
extension ProductProvider {
var maxProductCount: Int {
set(newValue) {
// set to what if I couldn't define private stored variable in extension to hold the most recent set value ?
}
get{
// how to return the most recent value set?
}
}
}
My question is in the comment of above code. How can I do that set and get for a variable in extension of protocol in Swift 4? If it is impossible, what are the workarounds possible?
Upvotes: 4
Views: 7602
Reputation: 460
The simplest way i think is define the variable in the protocol with the getter and setter. Then in your conform object you should declare the variable to conformance. An Example:
protocol AbstractObject {
var maxProductCount: Int { get set }
}
struct ConformObject: AbstractObject {
var maxProductCount: Int
}
So now you can use your variable in your default implementations
extension AbstractObject {
mutating func addOne() -> Int {
self.maxProductCount += 1
return self.maxProductCount
}
}
Upvotes: 4
Reputation: 658
Aside from the discussion if its a right way to achieve what you want, you can use object association.
public final class ObjectAssociation<T: AnyObject> {
private let policy: objc_AssociationPolicy
/// - Parameter policy: An association policy that will be used when linking objects.
public init(policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) {
self.policy = policy
}
/// Accesses associated object.
/// - Parameter index: An object whose associated object is to be accessed.
public subscript(index: AnyObject) -> T? {
get { return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? }
set { objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, policy) }
}
}
And in your extension
extension SomeType {
private static let association = ObjectAssociation<NSObject>()
var simulatedProperty: NSObject? {
get { return SomeType.association[self] }
set { SomeType.association[self] = newValue }
}
}
It is not possible to store Swift types via object association directly. You can store e.g. NSNumber instead of Int.
Source: https://stackoverflow.com/a/43056053/1811810
Upvotes: 1