Using the swift proxy pattern, how do you modify a private variable? - swift

I am experimenting with a basic proxy pattern in Swift playgrounds; I am not 100% familiar with it; but some videos are helping.
In my experiment, the subject, C is called through a proxy to perform said actions
ie:
A - Proxy - C
However, in my experiments I find out I can just call C itself directly, without even needing the proxy; so I am left wondering why bother with a proxy when I can call C directly anyway?
So I decided to make the variables in C private; but now I can't call them, or make modifications, and I am not sure how to resolve it.
I also tried a "decorator" pattern I found on stackoverflow to try to manipulate Cs variables, but still its marked private, so its not possible.
Also, the decorator pattern I found uses static variables. This makes me think well, why not just write a static function that creates c in memory, and then update the reference in proxy to that of the results of the static function.
I guess what I'm mis-understanding here is what is the point of a proxy class if you can just call the subject (in this case C) directly anyway?
Examples use Swift playground:
class A {
let proxy: Proxy = Proxy()
var funds: Int {
return self.proxy.funds
}
}
class Proxy {
private let c: C = C()
public var funds: Int {
return c.funds
}
private func canIGetFunds() -> Bool {
guard (self.funds > 0) else {
return false
}
return true
}
func subtractFunds(funds: Int = 0) {
if (canIGetFunds()) {
print ("you have enough funds")
willDebit(funds: funds)
}
else {
print ("Not enough funds")
}
}
private func willDebit(funds: Int = 0) {
self.c.funds -= funds
}
}
class C {
private (set) var funds: Int = 100
}
let a = A()
print (a.funds)
a.proxy.subtractFunds(funds: 50)
This code will throw up a compiler error on:
self.c.funds -= funds
because:
funds setter is inaccessible
the funds variable is indeed private.
So, I tried a decorator too; code I found from stackoverflow (its not mine):
#propertyWrapper
struct Announced<T, U> {
private var announcedFunction: (T) -> U
var wrappedValue: (T) -> U { announcedFunction }
init(wrappedValue: #escaping (T) -> U) {
announcedFunction = { args in
let rv = wrappedValue(args)
print("In: \(args)")
print("Out: \(rv)")
return rv
}
}
}
extension Wallet {
#Announced static var add: ((Int, Int)) -> Int = { $0.0 + $0.1 }
#Announced static var subtract: ((Int, Int)) -> Int = { $0.0 - $0.1 }
}
Now here the add and subtract are static variables; and the contents of the closure are of course wrong because I make no reference to the actual Wallet variables -- I've only put it like this to help with discussion.
The way I got around it is to try to make the (Int, Int) take in a Wallet class, and then return a modified Wallet object where the add or subtract has been completed
So something like this:
#Announced static var subtract: ((w:Wallet, Int)) -> Wallet = {
let newWallet = Wallet()
newWallet.cash = w.cash
newWallet.cash -= $0.1
return newWallet
}
But if I do this pattern, I don't see why I don't just write a static function and disregard this decorator.
I've even tried making C follow a delegate pattern where the Wallet is a delegate of C and adds, subtracts funds; but this too has an issue in that you can call C directly and because is its own delegate it has no reason to fail or throw up an error, etc.
So anyway, probably I'm just overcomplicating:
Whats the point of having a proxy if you can just call the subject directly and do your manipulation that way?
Is there a way to make the proxy pattern the only way you can call and make actions on the subject?
With thanks?

The easiest way is using public/internal setter
class C {
var funds: Int = 100
}
But if you define C in this same file with Proxy then you can use fileprivate(set) access modifier
class Proxy {
...
}
class C {
fileprivate(set) var funds: Int = 100
}

Related

The most efficient way to build tree from dictionary data

I have a dictionary with the following structure: [Point:[Line]], where:
Point - custom data structure that contains two coordinates (X, Y)
Line - tuple (Point, Point) that contains the first and last points of the line.
Key - first point of the line.
So, it is a dictionary of lines grouped by their first point, like following:
[a: [(a,b),(a,c)], b: [(b,c), (b,d)], c: [(c,d)] ]
The goal is to convert this dictionary into a list of data structures like following:
(a,b) -> (b,c) -> (c,d)
(a,b) -> (b,d)
(a,c) -> (c,d)
So, basically a tree with the root at the first point.
I tried to use builder pattern and stack to perform this operation, so I created a builder using first point and put in into stack, then started a while loop until stack is empty and then in the loop was removing current builder and creating new ones based on last & first points, the code looked like following:
import Foundation
typealias ProcessedLine = (UUID, [LineModel])
typealias LinePointDict = [Point: [Line]]
class LineAggregator {
var builderStack: Stack<LineModel.LineModelBuilder>
let startPointMap: LinePointDict
var result: ProcessedLine
var currentBuilder: (Point, LineModel.LineModelBuilder)?
let startPoint: Point
init(LineUid: UUID, startPointMap: LinePointDict, startPoint: Point) {
self.builderStack = Stack<LineModel.LineModelBuilder>()
self.startPointMap = startPointMap
self.result = (LineUid, [])
self.startPoint = startPoint
self.currentBuilder = nil
}
func getLineAggregation() -> ProcessedLine {
for Line in startPointMap[startPoint]! {
var bldr = LineModel.LineModelBuilder(initialLineUuid: result.0)
bldr = bldr.addLine(Line: Line)
builderStack.push(bldr)
}
return aggregateModels()
}
func aggregateModels() -> ProcessedLine {
while !builderStack.isEmpty() {
takeBuilderFromStack()
aggregateLine()
}
return result
}
/**
* This functions pops Builder object from stack if the stack is not empty and sets it as a Current object to be processed.
* #param object
* #return
*/
private func takeBuilderFromStack() {
if(!builderStack.isEmpty()) {
let curBuilder = builderStack.pop()!
currentBuilder = (curBuilder.getLastElement(), curBuilder)
}
}
private func aggregateLine() {
if currentBuilder?.1.isLastAdded() ?? true {
//If there is only one Line in the Line model
if(currentBuilder!.1.isLastAddedLineLast()) {
result.1.append(currentBuilder!.1.build())
return
}
if(!builderStack.isEmpty()) {
print("ERROR: Empty builder stack! Such situation should not happen. Pay attention at it.");
builderStack.removeAll()
}
return
}
if currentBuilder != nil {
for Line in startPointMap[currentBuilder!.0]! {
var newBuilder = LineModel.LineModelBuilder(builder: currentBuilder!.1)
newBuilder = newBuilder.addLine(Line: Line)
if Line.isLast {
result.1.append(newBuilder.build())
} else {
builderStack.push(newBuilder)
}
}
}
}
}
This solution is a very straightforward one. It works, but I have a very large amount of data in the dictionary, and the number of combinations is even larger, so this algorithm is extremely slow and not memory efficient.
The main slowness is caused by adding and retrieving data to/from stack which has following implementation:
import Foundation
protocol Stackable {
associatedtype Element
func peek() -> Element?
mutating func push(_ element: Element)
#discardableResult mutating func pop() -> Element?
}
extension Stackable {
var isEmpty: Bool { peek() == nil }
}
struct Stack<Element>: Stackable where Element: Equatable {
private var storage = [Element]()
func peek() -> Element? { storage.first }
mutating func push(_ element: Element) { storage.append(element) }
mutating func pop() -> Element? { storage.popLast() }
func size() -> Int { storage.count }
func isEmpty() -> Bool { storage.isEmpty }
mutating func removeAll() { storage.removeAll() }
}
extension Stack: Equatable {
static func == (lhs: Stack<Element>, rhs: Stack<Element>) -> Bool { lhs.storage == rhs.storage }
}
extension Stack: CustomStringConvertible {
var description: String { "\(storage)" }
}
extension Stack: ExpressibleByArrayLiteral {
init(arrayLiteral elements: Self.Element...) { storage = elements }
}
And another bottleneck is related to copying data and deinit method.
I was trying to find a better solution, but couldn't find anything yet. Would be grateful for any suggestions. Thanks.
While the builder pattern is useful, I think in this case it just complicates the straight-forward solution, although as you'll see, I'll present a couple that are more complicated, but those are based on increased performance optimizations on the first simple solution.
As you you noted, initializing and deinitializing classes is kind of slow. Actually the worst part is the dynamic memory allocation. Classes are powerful and definitely have their uses, but they're not the fastest tool in the Swift toolbox. Unless you make methods final, calling them can require a virtual dispatch. That can happen with protocols too depending on the particulars of their declaration, though in that case it's called "witness table thunking". But the worst part about classes is that their instances can be littered pretty much anywhere in memory. That's hell on the processor's on-chip cache. So for performance try to avoid dynamic dispatch, and reference types (ie, classes), and when you do need to allocate memory (such as Array or Dictionary), try to allocate all you need at once, and reuse it as much as possible. In Swift that requres some thought because of copy-on-write. You can easily end up allocating memory when you didn't intend to.
I present three solutions. Each one is more complicated, but also (hopefully) faster than the previous one. I'll explain why, and what to look out for. I should mention that I am not including the simplest solution. It is much like my first solution but with local variable arrays. The performance would not be especially good, and you're question makes it clear that performance is an issue.
First there's some boiler plate. To code it up and test it, I needed to define your Point and Line types, plus a few others I use for convenience, as well as some extensions purely for generating output. This code is common to all three solutions. Substitue your own definitions for Point and Line.
struct Point: Hashable
{
// This is just to give the points uniqueness, and letter names
static private let pointNames = [Character]("abcdefghijklmnopqrstuvwxyz")
static private var curNameIndex = 0
static private var nextID: Character
{
defer { curNameIndex += 1 }
return pointNames[curNameIndex]
}
let id = nextID
}
typealias Line = (Point, Point)
typealias Graph = [Point: [Line]]
typealias Path = [Line]
// Now we add some extensions for convenient output
extension Point: CustomStringConvertible {
var description: String { "\(id)" }
}
extension String.StringInterpolation
{
mutating func appendInterpolation(_ line: Line) {
appendLiteral("(\(line.0),\(line.1))")
}
mutating func appendInterpolation(_ lines: [Line]) {
appendLiteral(lines.map { "\($0)" }.joined(separator: "->"))
}
}
You mention that Point has an X and Y, but for this problem it doesn't matter. You just need unique "things" to serve as end-points for your Line instances.
Then I declared the inputs from your example:
let (a, b, c, d) = (Point(), Point(), Point(), Point())
let input = [ a: [(a,b),(a,c)], b: [(b,c), (b,d)], c: [(c,d)] ]
With the common code out of the way, here are the actual solutions:
Solution 1
Although the recursion introduces overhead all by itself, the main problem with the most straight-forward solution is that it requres local arrays that are allocated and deallocated up and down the call stack. The dynamic memory allocations and deallocations for them are actually the main performance problem with the simple recursive solution.
The solution is to attempt to pre-allocate working storage, and re-use it all through-out the recursion, or at least make reallocations rare.
One way would be to allocate the working arrays at the top level and pass them in as inout parameters. Another is to make them mutable properties of a struct (actually, a class wouldn't be too bad in this case, because you only allocate one instance). I chose the latter approach.
As I mentioned in my comment, I think of this problem as a graph theory problem.. Point = node. Line = edge. Though it's not explicitly stated, I assume there are no cycles. Putting in code to detect cycles isn't that hard, but would complicate the solution slightly. I also assume that the output should not contain entries with just one Line, because your example doesn't include any examples of that.
struct PathFinderVersion1
{
private let graph: Graph
private var pathList = [Path]()
private var currentPath = Path()
private init(for graph: Graph)
{
self.graph = graph
self.pathList.reserveCapacity(graph.count)
self.currentPath.reserveCapacity(graph.count)
}
static func pathList(for graph: Graph) -> [Path]
{
var pathFinder = Self(for: graph)
return pathFinder.makePathLists()
}
private mutating func makePathLists() -> [Path]
{
for src in graph.keys
{
for edge in graph[src]!
{
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
appendAllPaths()
currentPath.removeLast()
}
}
return pathList
}
private mutating func appendAllPaths()
{
assert(currentPath.count > 0, "currentPath must not be empty on entry")
guard let src = currentPath.last?.1 else { return }
guard let edges = graph[src] else
{
if currentPath.count > 1 {
pathList.append(currentPath)
}
return
}
for edge in edges
{
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
appendAllPaths()
currentPath.removeLast()
}
}
}
Apart from the init, and static wrapper function, pathList(for:), the algorithm is really just two functions. The initializer is where I pre-allocate the working storage. Assuming there is an entry in the graph Dictionary for each Point, no path can ever be longer than there entries keys in the graph ... at least not without cycles, so currentPath is initialized with that much capacity. Similar thinking applies to the other working arrays. The pathList is likely to be be larger than graph.count, but unless there are a lot of unconnected Lines, it will need to be at least as big as graph is.
makePathLists() is the part that gets thing started, extracting the Point and array of Line for each of its entries. It initializes the first entry in a currentPath, then calls appendAllPaths() to recursively append new Line instances to currentPath on the way down. When it reaches the end, it has found a complete path, so it adds the currentPath to the pathList. On the way back up, it removes the entry it added from currentPath so that it's in a state that it can be reused again to go down another path in the graph.
Once makePathLists() has iterated over all its keys and appendAllPaths() has recursed for each one, pathList contains the result. I'm not 100% sure it's in the format you want. It's basically a flat list of all the paths it found. So it's kind of one data structure. But all the paths will be grouped together according to the starting point in the line, so splitting it into smaller lists is easy enough, if that's what you actually want.
In any case, the re-use of existing storage is where this version gets most of its performance.
You can call it like this:
print("Version 1")
for path in PathFinderVersion1.pathList(for: input) {
print("\(path)")
}
And here's the output for the data I set up as input:
Version 1
(b,c)->(c,d)
(a,b)->(b,c)->(c,d)
(a,b)->(b,d)
(a,c)->(c,d)
The exact order changes slightly from run-to-run because Dictionary doesn't necessarily hand out its keys in an order that is consistent from run to run, even if they are inserted exactly the same way every time. I tested each version to verify they all emit the same output (and so should you), but I won't include the output again for the other versions.
Solution 2
This version is based on solution 1, so everything about it applies to this version too. What's different is the addition of the dynamic programming technique of caching intermediate values. Basically I cache paths along the way, so that when I encounter them again, I don't have do all that recursion. I can just used the cached path instead.
There is one snag with this caching, it requres allocating some local caches, which introduces dynamic memory allocation again. However hope is not lost. For starters, assuming lots of nodes in the graph have multiple input edges (ie, lots of different lines connect to the same line), the result should be a win overall from being able to avoid a vast amount of recursion. Additionally i, re-use the local caches, so I only ever have to actually allocate a new one when I recurse deeper than the previous maximum depth reached. So while some allocation does happen, it's minimized.
All that cache handling makes the code longer, but faster.
To make the code more readable I put the local caching in nested struct. Here's the code for version 2:
struct PathFinderVersion2
{
private typealias CachedPath = Path.SubSequence
private typealias CachedPaths = Array<CachedPath>
private let graph: Graph
private var pathList = [Path]()
private var currentPath = Path()
private var pathCache = [Point: CachedPaths]()
private struct LocalPathCache
{
var cache = [CachedPath]()
var pathListIndex: Int
var curPathLength: Int
mutating func updateLocalPathCache(from pathList: [Path])
{
while pathListIndex < pathList.endIndex
{
let pathToCache =
pathList[pathListIndex][curPathLength...]
cache.append(pathToCache)
pathListIndex += 1
}
}
mutating func update(
mainCache: inout [Point: CachedPaths],
for src: Point)
{
if cache.count > 0 {
mainCache[src] = cache
}
}
}
private var localCaches = [LocalPathCache]()
private mutating func getLocalCache(
pathListIndex: Int,
curPathLength: Int) -> LocalPathCache
{
if var cache = localCaches.last
{
localCaches.removeLast()
cache.cache.removeAll(keepingCapacity: true)
cache.pathListIndex = pathListIndex
cache.curPathLength = curPathLength
return cache
}
return LocalPathCache(
pathListIndex: pathListIndex,
curPathLength: curPathLength
)
}
private mutating func freeLocalCache(_ cache: LocalPathCache) {
localCaches.append(cache)
}
private init(for graph: Graph)
{
self.graph = graph
self.pathList.reserveCapacity(graph.count)
self.currentPath.reserveCapacity(graph.count)
self.pathCache.reserveCapacity(graph.count)
}
static func pathList(for graph: Graph) -> [Path]
{
var pathFinder = Self(for: graph)
return pathFinder.makePathLists()
}
private mutating func makePathLists() -> [Path]
{
for src in graph.keys
{
for edge in graph[src]!
{
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
appendAllPaths()
currentPath.removeLast()
}
}
return pathList
}
private mutating func appendAllPaths()
{
assert(currentPath.count > 0, "currentPath must not be empty on entry")
guard let src = currentPath.last?.1 else { return }
if updatePathListFromCache(for: src) { return }
guard let edges = graph[src] else
{
if currentPath.count > 1 {
pathList.append(currentPath)
}
return
}
var localCache = getLocalCache(
pathListIndex: pathList.endIndex,
curPathLength: currentPath.endIndex
)
defer { freeLocalCache(localCache) }
for edge in edges
{
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
appendAllPaths()
currentPath.removeLast()
localCache.updateLocalPathCache(from: pathList)
}
localCache.update(mainCache: &pathCache, for: src)
}
mutating func updatePathListFromCache(for src: Point) -> Bool
{
if let cachedPaths = pathCache[src]
{
let curPathIndex = currentPath.endIndex
for path in cachedPaths
{
currentPath.append(contentsOf: path)
pathList.append(currentPath)
currentPath.removeSubrange(curPathIndex...)
}
return true
}
return false
}
}
Solution 3
Solutions 1 and 2 still use recursion. Recursion is elegant, and nice to think about, because you can express a problem as a slightly simpler problem plus a bit. But unless it's tail-recursive, compilers can't optimize it particularly well. So the solution to that problem is to use iteration instead of recursion.
Turning a recursive algorithm into an iterative one is not always so easy, and can result in ugly code. That is the definitely the case here. There might be a simpler iterative algorithm, but I don't know it. So I basically replaced recursion with a state machine + stack. I've used this technique before for recursive code the desperately needed to be faster, and it does work. The code is a total pain for a human to read and maintain, but compilers can optimize the hell out of it.
This version still uses the cached intermediate solutions from version 2.
struct PathFinderVersion3
{
private typealias CachedPath = Path.SubSequence
private typealias CachedPaths = Array<CachedPath>
private let graph: Graph
private var pathList = [Path]()
private var currentPath = Path()
private var pathCache = [Point: CachedPaths]()
private struct LocalPathCache
{
var cache = [CachedPath]()
var pathListIndex: Int
var curPathLength: Int
mutating func updateLocalPathCache(from pathList: [Path])
{
while pathListIndex < pathList.endIndex
{
let pathToCache =
pathList[pathListIndex][curPathLength...]
cache.append(pathToCache)
pathListIndex += 1
}
}
mutating func update(
mainCache: inout [Point: CachedPaths],
for src: Point)
{
if cache.count > 0 {
mainCache[src] = cache
}
}
}
private var localCaches = [LocalPathCache]()
private mutating func getLocalCache(
pathListIndex: Int,
curPathLength: Int) -> LocalPathCache
{
if var cache = localCaches.last
{
localCaches.removeLast()
cache.cache.removeAll(keepingCapacity: true)
cache.pathListIndex = pathListIndex
cache.curPathLength = curPathLength
return cache
}
return LocalPathCache(
pathListIndex: pathListIndex,
curPathLength: curPathLength
)
}
private mutating func freeLocalCache(_ cache: LocalPathCache) {
localCaches.append(cache)
}
private init(for graph: Graph)
{
self.graph = graph
self.pathList.reserveCapacity(graph.count)
self.currentPath.reserveCapacity(graph.count)
self.pathCache.reserveCapacity(graph.count)
}
static func pathList(for graph: Graph) -> [Path]
{
var pathFinder = Self(for: graph)
return pathFinder.makePathLists()
}
private mutating func makePathLists() -> [Path]
{
for src in graph.keys
{
for edge in graph[src]!
{
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
appendAllPaths()
currentPath.removeLast()
}
}
return pathList
}
struct Stack<T>
{
var storage: [T] = []
var isEmpty: Bool { storage.isEmpty }
var count: Int { storage.count }
init(capacity: Int) { storage.reserveCapacity(capacity) }
mutating func push(_ element: T) { storage.append(element) }
mutating func pop() -> T? { storage.popLast() }
}
private mutating func appendAllPaths()
{
assert(currentPath.count > 0, "currentPath must not be empty on entry")
enum State
{
case entry
case inLoopPart1
case inLoopPart2
case exit
}
var state: State = .entry
typealias StackElement =
(Point, Int, Line, [Line], LocalPathCache, State)
var stack = Stack<StackElement>(capacity: graph.count)
var src: Point! = nil
var edges: [Line]! = nil
var edgeIndex: Int = 0
var edge: Line! = nil
var localCache: LocalPathCache! = nil
outer: while true
{
switch state
{
case .entry:
if let s = currentPath.last?.1 {
src = s
}
else
{
state = .exit
continue outer
}
if updatePathListFromCache(for: src)
{
state = .exit
continue outer
}
if let e = graph[src] { edges = e }
else
{
if currentPath.count > 1 {
pathList.append(currentPath)
}
state = .exit
continue outer
}
localCache = getLocalCache(
pathListIndex: pathList.endIndex,
curPathLength: currentPath.endIndex
)
edgeIndex = edges.startIndex
state = .inLoopPart1
continue outer
case .inLoopPart1:
if edgeIndex < edges.endIndex
{
edge = edges[edgeIndex]
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
// Simulate function call
stack.push((src, edgeIndex, edge, edges, localCache, .inLoopPart2))
state = .entry
continue outer
}
localCache.update(mainCache: &pathCache, for: src)
state = .exit
case .inLoopPart2:
localCache.updateLocalPathCache(from: pathList)
edgeIndex += 1
state = .inLoopPart1 // Simulate goto top of inner loop
case .exit: // Simulate return
if let c = localCache { freeLocalCache(c) }
if let savedState = stack.pop()
{
(src, edgeIndex, edge, edges, localCache, state) = savedState
currentPath.removeLast()
}
else { break outer }
}
}
assert(stack.isEmpty)
}
mutating func updatePathListFromCache(for src: Point) -> Bool
{
if let cachedPaths = pathCache[src]
{
let curPathIndex = currentPath.endIndex
for path in cachedPaths
{
currentPath.append(contentsOf: path)
pathList.append(currentPath)
currentPath.removeSubrange(curPathIndex...)
}
return true
}
return false
}
}
Ummm... yeah, there it is in all its ugly glory. It works. It's fast. Good luck maintaining it.
The question is whether the speed is worth it when weighed against the readability issues and maintenance headaches, and that all depends on the application requirements. In my opinion that speed would have to be pretty darn important to put up with maintaining this version, and I'm normally fine with putting up with some ugliness to get speed in critical code. Somehow, this version, written in a language that doesn't even have a goto statement is nonetheless a poster-child for why goto is considered bad in the first place.
Solution 4 (Bonus)
Originally I just mentioned that you could parallelize it, but I didn't implement it. I decided that for completeness, a parallelization example really should be included.
I chose to parallelize solution 1, but all three of the previous solutions can be parallelized in exactly the same way. The changes that have to be made are to add the split method, and modify the static pathList(for:) method as well as the private makePathLists instance method. You also need a concurrent DispatchQueue. I create a global one for this example, but you can use an existing one. Don't use DispatchQueue.main for this, if you want your app to be responsive while processing.
Here's the code:
import Foundation
let dispatchQueue =
DispatchQueue(label: "PathFinder-\(UUID())",attributes: .concurrent)
struct PathFinderVersion4
{
private let graph: Graph
private var pathList = [Path]()
private var currentPath = Path()
private init(for graph: Graph)
{
self.graph = graph
self.pathList.reserveCapacity(graph.count)
self.currentPath.reserveCapacity(graph.count)
}
public static func pathList(for graph: Graph) -> [Path]
{
let concurrency = min(4, graph.count)
let pointGroups = split(.init(graph.keys), numberOfGroups: concurrency)
var pathLists = [[Path]](repeating: [], count: concurrency)
let waitSems = Array(
repeating: DispatchSemaphore(value: 0),
count: concurrency
)
for groupIndex in pointGroups.indices
{
dispatchQueue.async
{
defer { waitSems[groupIndex].signal() }
var pathFinder = Self(for: graph)
pathLists[groupIndex] =
pathFinder.makePathLists(for: pointGroups[groupIndex])
}
}
// Need to signal each semaphore after waiting or will crash on return.
// See Apple documentation for DispatchSemaphore
waitSems.forEach { $0.wait(); $0.signal() }
var result = [Path]()
result.reserveCapacity(pathLists.reduce(0) { $0 + $1.count })
pathLists.forEach { result.append(contentsOf: $0) }
return result
}
private static func split<Value>(
_ values: [Value],
numberOfGroups: Int) -> [[Value]]
{
var groups = [[Value]]()
groups.reserveCapacity(numberOfGroups)
let groupSize = values.count / numberOfGroups
+ (values.count % numberOfGroups == 0 ? 0 : 1)
var valueIndex = values.startIndex
while valueIndex < values.endIndex
{
var group = [Value]()
group.reserveCapacity(groupSize)
let valueEnd = min(valueIndex + groupSize, values.endIndex)
while valueIndex < valueEnd
{
group.append(values[valueIndex])
valueIndex += 1
}
groups.append(group)
}
return groups
}
private mutating func makePathLists(for points: [Point]) -> [Path]
{
for src in points
{
for edge in graph[src]!
{
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
appendAllPaths()
currentPath.removeLast()
}
}
return pathList
}
private mutating func appendAllPaths()
{
assert(currentPath.count > 0, "currentPath must not be empty on entry")
guard let src = currentPath.last?.1 else { return }
guard let edges = graph[src] else
{
if currentPath.count > 1 {
pathList.append(currentPath)
}
return
}
for edge in edges
{
assert(edge.0 == src, "sanity check failed")
currentPath.append(edge)
appendAllPaths()
currentPath.removeLast()
}
}
}

Require calling method M after setting property P

I have a property and a method:
class C {
var myProperty = ""
func myFunc() {
}
}
I would like to have a rule that when you set myProperty you must then proceed to call myFunc. Of course I can have a mental rule that requires this, but a mental contract is no contract at all. I want to enforce this contract through the class's API.
(NOTE All of this is purely about what goes on inside C. Both myProperty and myFunc can be private as far as visibility outside C is concerned; that doesn't affect the problem.)
Obviously we can do this with a setter observer:
class C1 {
var myProperty = "" {
didSet {
self.myFunc()
}
}
func myFunc() {
}
}
However, there's something I don't like about that solution: it relies upon what amounts to a hidden side effect. It is up to me to know that saying self.myProperty = "..." also triggers a call to myFunc. I don't like that kind of hidden side effect; it makes my code harder to understand, and violates one of my key programming principles, Say What You Mean.
What do I mean? I mean something like this:
self.setMyPropertyAndCallMyFunc("...")
I like that, because it tells me exactly what this call does every time it occurs in my code. So we could write this:
class C2 {
var myProperty = ""
func myFunc() {
}
func setMyPropertyAndCallMyFunc(_ s:String) {
self.myProperty = s
self.myFunc()
}
}
But there's a problem with that, namely that it is now possible to set myProperty without calling myFunc, breaking the rule that we set out to enforce in the first place! The only way I've found to enforce that rule is to have another class that defends the property with privacy. For example:
class C3 {
class Inner {
private(set) var myProperty = ""
private func myFunc() {
}
func setMyPropertyAndCallMyFunc(_ s:String) {
self.myProperty = s
self.myFunc()
}
}
let inner = Inner()
}
That is in fact what I'm doing, but it seems a bit nutty to have a second class just to enforce these privacy and naming rules. My question is: Is there another way?
Yes, though I don't know if it's actually any better. You can hide myProperty inside of a closure rather than inside of a class/struct. For example:
class C {
public var myProperty: String { return _myPropertyGetter() }
public func setMyPropertyAndCallMyFunc(value: String) {
_myPropertySetter(self, value)
}
func myFunc() {
print("myFunc")
}
private let (_myPropertyGetter, _myPropertySetter): (() -> String, (C, String) -> ()) = {
var property = ""
return ({ property }, { property = $1; $0.myFunc() })
}()
}
let c = C()
c.myProperty
c.setMyPropertyAndCallMyFunc(value: "x")
c.myProperty
There's a lot of complexity here, like passing self to _setMyPropertyAndCallMyFunc to allow myFunc to live outside the closure, and maybe some of that could be dispensed with. But the basic idea is to generate two functions that are the only functions that have access to the property storage, making it "super-private" without creating an inner class.
If you don't need myFunc() to be public (and from your Inner example, I think you don't), then you can do it a little simpler, and this almost might be better than Inner.
class C {
public var myProperty: String { return _myPropertyGetter() }
public func setMyPropertyAndCallMyFunc(value: String) { _myPropertySetter(value) }
private let (_myPropertyGetter, _myPropertySetter): (() -> String, (String) -> ()) = {
var property = ""
func myFunc() {
print("myFunc")
}
return ({ property }, { property = $0; myFunc() })
}()
}

Swift override all setters and getters of a subclass

I would like to override a setter/getter one time for but for all the properties for a class in swift
This my class. I want to call Realm each time I am adding a new value
class House : Object
{
var a:String
{
set {
do {
let realm = try Realm()
try realm.write {
a = newValue
}
}
catch {
}
}
}
var b:String
{
set {
do {
let realm = try Realm()
try realm.write {
b = newValue
}
}
catch {
}
}
}
}
There is no way in Swift how you can overwrite setters for all properties at once.
What you could generally do though is use:
overwritten setters per property
abstract computed properties wrapping low-level properties
intercept getters and setters by KVC accessor methods (e.g. is<Key>, get<Key>, …) and rely only on untyped dynamic KVC-based access via valueForKey(Path):, if you want to apply the decorated behavior (which you might want to avoid for this reason)
But Realm is using custom getters and setters under the hood, which are dynamically overwritten in an dynamically inserted intermediate class at runtime and relies on the presence of those. So the only approach, which is really feasible is having dynamic stored properties declared and adding for each of those an extra property, based on those.
var storedPropertyA: String = ""
var computedPropertyA: String {
get {
// add your extra behavior here
return storedPropertyA
}
set {
// add your extra behavior here
self.storedPropertyA = newValue
}
}
Beside that there is an alternative way of using the decorator pattern and decorate your whole object with extra behavior. In Swift, you could have your object and your decorator implement a common protocol, which defines your properties.
protocol HousingProperties {
var a: String { get set }
}
class House: HousingProperties {
var a: String = ""
}
class HouseDecorator: HousingProperties {
internal var house: House
init(house: House) { self.house = house }
var a: String {
// add your extra behavior here
self.house.a = a
}
}
Still I would NOT recommend to intercept property setters and getters for the purpose you intend here. Instead I'd advise to structure your application's architecture in a way, that allows you to be aware whether there is a write transaction or not and let the responsibility of making a write transaction in the hands of the code, which tries to modify objects.
Let me explain why:
Realm is using a multiversion concurrency control algorithm to manage persisted data and achieve thread-safety. This makes sure that different threads can read data at any point in time without having to read-lock and trying to synchronize these. Instead when a write is happening, all accessors are notified that there is new data and try to move on to the newest transaction. Until that has happened, all versions between the oldest data version, which is still used by a thread and the one written have to be retained. They can be first released when all threads advanced their commit pointers. If you do a lot of small transactions, you risk that your file size will blew up to unnecessary high values. For that reason, we recommend to batch write transactions to large changesets.
There is one hack to kind of attain what the poster is looking for, however possibly not advisable... Anyway; you can can create your own assignment operators that does whatever you want to do in realm prior to assigning the values
class MyType {
var myInt : Int = 0
var myString : String = ""
init(int: Int, string: String) {
myInt = int
myString = string
}
}
infix operator === {}
func ===<T>(lhs: T, rhs: T) -> T? {
Realm() // replace with whatever Realm()-specific stuff you want to do
return rhs
}
protocol MyAddableTypes {
func + (lhs: Self, rhs: Self) -> Self
}
extension String : MyAddableTypes {}
extension Int : MyAddableTypes {}
infix operator +== {} // ... -== similarily
func +==<T: MyAddableTypes>(lhs: T, rhs: T) -> T? {
Realm() // replace with whatever Realm()-specific stuff you want to do
return lhs+rhs
}
func Realm() {
// ...
print("Called realm")
}
var a = MyType(int: 1, string: "foo")
a.myString === "bar" // calls Realm(). After operation: a.myString = "bar"
a.myInt +== 1 // calls Realm(). After operation: a.myInt = 2
I thought I'd also mention that if you only want to do "Realm stuff" when a value is set (from your example: prior to setting a value, specifically), then the willSet method, used with stored properties, doesn't need to look so messy (nested closures), and personally, I would prefer this method
func Realm() {
print("Called realm")
}
class MyType {
// This isn't so messy, is it?
var myInt : Int = 0 { willSet { priorToSetValue(newValue) } }
var myString : String = "" { willSet { priorToSetValue(newValue) } }
var myDouble : Double = 0.0 { willSet { priorToSetValue(newValue) } }
private func priorToSetValue<T> (myVar: T) {
// replace with whatever Realm()-specific stuff you want to do,
// possibly including doing something with your new value
Realm()
}
init(int: Int, double: Double, string: String) {
myInt = int
myDouble = double
myString = string
}
}
var a = MyType(int: 1, double: 1.0, string: "foo")
a.myString = "bar"
print(a.myString) // calls Realm(). After operation: a.myString = "bar"
a.myInt += 1 // calls Realm(). After operation: a.myInt = 2

Creating a generic singleton

This is a bit of a head banger (for me). Basically I want to have 2 different singletons that inherit from the same class. In either I want to use a certain class which itself is derived. So I have Utility and both AUtil:Utility and BUtil:Utility. And Singleton that is used as ASingleton using AUtility in its stomach and B respectively. I failed on all frontiers. The last attempt was a factory pattern which simply got Swift 1.2 to Segfault:
protocol Initializable { init() }
class A:Initializable {
var x = "A"
required init() {}
}
class B:Initializable {
var x = "B"
required init() {}
}
class C {
let t:Initializable
init(t:Initializable) {
self.t = t
println(t)
}
func factory() {
println(t.dynamicType())
}
}
As said I also tried to make the following pattern generic:
private let _SingletonSharedInstance = StaticClass()
class StaticClass {
class var sharedInstance : StaticClass {
return _SingletonSharedInstance
}
}
let s = StaticClass.sharedInstance
(This one isn't generic as you see. But all my attempts failed and so I show my starting point.)
Anyway I seem to be lost between doom and death.
Do you mean something like this?
protocol Initializable: class { init() }
private var instances = [String: Initializable]()
func singletonInstance<T: Initializable>(_ ty: T.Type = T.self) -> T {
let name = NSStringFromClass(ty)
if let o = (instances[name] as? T) {
return o
}
let o = ty()
instances[name] = o
return o
}
An use-side of it, for instance.
class Foo: Initializable { required init() {} }
class Bar: Initializable { required init() {} }
let foo1 = singletonInstance() as Foo // or `singletonInstance(Foo.self)`
let foo2 = singletonInstance() as Foo
assert(foo1 === foo2)
let bar1 = singletonInstance() as Bar
let bar2 = singletonInstance() as Bar
assert(bar1 === bar2)
(I've tested the code above and got it to work in Swift 1.2.)
Inspired by findalls implementation, I build my own singleton generator, which is a little more powerful.
You can create a singleton of any Class or Structure type in Swift. The only thing you have to do is to implement one of two different protocols to your type and use Swift 2.0 or newer.
public protocol SingletonType { init() }
private var singletonInstances = [String: SingletonType]()
extension SingletonType {
// this will crash Xcode atm. it's a Swift 2.0 beta bug. Bug-ID: 21850697
public static var singleton: Self { return singleton { $0 } }
public static func singleton(setter: (_: Self) -> Self) -> Self {
guard let instance = singletonInstances["\(self)"] as? Self else {
return setInstance(self.init(), withSetter: setter, overridable: true)
}
return setInstance(instance, withSetter: setter, overridable: false)
}
private static func setInstance(var instance: Self, withSetter setter: (_: Self) -> Self, overridable: Bool) -> Self {
instance = restoreInstanceIfNeeded(instance1: instance, instance2: setter(instance), overridable: overridable)
singletonInstances["\(self)"] = instance
return instance
}
private static func restoreInstanceIfNeeded(instance1 i1: Self, instance2 i2: Self, overridable: Bool) -> Self {
// will work if the bug in Swift 2.0 beta is fixed !!! Bug-ID: 21850627
guard i1.dynamicType is AnyClass else { return i2 }
return ((i1 as! AnyObject) !== (i2 as! AnyObject)) && !overridable ? i1 : i2
}
}
This may look a little scary, but don't be afraid of this code. The public function inside the protocol extension will create two access points for you.
For example you will be able to write code like this now:
// extend your type: as an example I will extend 'Int' here
extension Int : SingletonType {} // nothing else to do, because Int already has an 'init()' initializer by default
// let the magic happen
Int.singleton // this will generate a singleton Int with 0 as default value
Int.singleton { (_) -> Int in 100 } // should set your Int singleton to 100
Int.singleton { $0 - 55 } // your singleton should be 45 now
// I need to mention that Xcode will produce the setter like this and trow an error
Int.singleton { (yourCustomInstanceName) -> Self in // replace 'Self' with 'Int' and you should be fine
return yourCustomInstanceName
}
// btw. we just ignored the return value everywhere
print(Int.singleton) // will print 45 here
var singleton2 = Int.singleton { $0 + 5 }
singleton2 += 10
print(Int.singleton) // should print 50, because 'singleton2' is just a copy of an Int value type
class A : SingletonType {
var name = "no name"
required init() {}
}
A.singleton { $0; let i = A(); i.name = "hello world"; return i } // custom init on first singleton call for type A
print(A.singleton.name)
print(A.singleton { $0.name = "A"; return $0 }.name)
print(A.singleton.name)
// should print "hello world" and twice the string "A"
If you have any idea how to enhance this code and make it even safer, please let me know. I will push this code on GitHub (MIT License) soon, so everyone can benefit from it.
UPDATE: I modified the code a little so you can now pass a custom initialized instance of a class with the setter function when its called the first time.
UPDATE 2: I removed ClassInstance protocol and modified the private restore function. The Instance protocol is now called SingletonType. The setter function is not optional anymore. Right now Xcode 7 beta 3 will crash and provide an illegal instruction: 4 error when you will call the getter. But this is a confirmed beta bug.

Add "for in" support to iterate over Swift custom classes

As we know, we can use the for..in loop to iterate across Arrays or Dictionaries. However, I would like to iterate over my own CustomClass like this:
for i in CustomClass {
someFunction(i)
}
What operations/protocols does CustomClass have to support for this to be possible?
Say you have a class "Cars" that you want to be able to iterate over using a for..in loop:
let cars = Cars()
for car in cars {
println(car.name)
}
The simplest way is to use AnyGenerator with the classes like this:
class Car {
var name : String
init(name : String) {
self.name = name
}
}
class Cars : SequenceType {
var carList : [Car] = []
func generate() -> AnyGenerator<Car> {
// keep the index of the next car in the iteration
var nextIndex = carList.count-1
// Construct a AnyGenerator<Car> instance, passing a closure that returns the next car in the iteration
return anyGenerator {
if (nextIndex < 0) {
return nil
}
return self.carList[nextIndex--]
}
}
}
To try a complete working sample add the two classes above and then try to use them like this, adding a couple of test items:
let cars = Cars()
cars.carList.append(Car(name: "Honda"))
cars.carList.append(Car(name: "Toyota"))
for car in cars {
println(car.name)
}
That's it, simple.
More info: http://lillylabs.no/2014/09/30/make-iterable-swift-collection-type-sequencetype
All of the above answers can be a little tricky. If you have an array in your class, which you want to iterate over (like in #Lee Whitney's answer), there's a much simpler way to implement it. You have the following class, CustomClass:
class CustomClass: SequenceType {
let array: [String]
init(array: [String]) {
self.array = array
}
func generate() -> IndexingGenerator<[String]> {
return array.generate()
}
}
Simple as that. Tested to work in the latest Xcode version (6.1 at the time of writing), and iOS 8.1.2. This code should be stable through future versions, though.
P.S. With generics, you can easily do your own Array replica by following this pattern, and only implement the methods which you want.
#Matt Gibson is correct. However, I would like to add more information for future reference.
From Advanced Swift:
This code:
for x in someSequence {
...
}
Is converted into this:
var __g = someSequence.generate()
while let x = __g.next() {
...
}
Therefore, one must adopt Sequence, which gives the class generate() and next(). Here are these protocols:
protocol Generator {
typealias Element
mutating func next() -> Element?
}
protocol Sequence {
typealias GeneratorType : Generator
func generate() -> GeneratorType
}
That would be the SequenceType protocol, and its related Generator protocol.
The SequenceType protocol says that the class must implement generate(), which returns something that conforms to the Generator protocol, which is the bit that does the actual work; the Generator protocol is the one with the all-important next() method.
There's an example of implementing it to allow for..in in the WWDC 2014 video "Advanced Swift" (in the generics example "A Simple Generic Stack", starting around slide 183.)
The basic info on which protocol to implement for for..in is in the Statements section of the documentation, which gives a brief overview of SequenceType and Generator
NOTE AnyGenerator and SequenceType are old types that do not exist in recent versions. You need to implement Sequence protocol now.
There are two ways to implement Sequence.
Conform to Sequence, IteratorProtocol at the same time by just implementing next() method. This approach is the simplest and there is an example in the headers. See Sequence.swift. Implementing both protocols at the same time could be non-realistic or not fulfill your needs. (It might prevent two different instances to be iterated at the same time, etc)
Conform to Sequence and return an object that implements IteratorProtocol. I think this is the most common case in real world classes (when things become a bit complicated, not Hello Worlds). There is also an example in the Sequence.swift
Below is an example of approach 2. An custom class (Linked List) which is iterable:
/// Linked List Node:
public class LinkedListNode <T> {
public internal(set) var value: T
public internal(set) var next: LinkedListNode<T>?
internal init(_ value: T) {
self.value = value
self.next = nil
}
}
/// Linked List with append method only.
public class LinkedList<T> {
public internal(set) var first: LinkedListNode<T>? = nil
public internal(set) var last: LinkedListNode<T>? = nil
/// Appends a new node.
public func append(_ value: T) {
if first == nil {
first = LinkedListNode(value)
last = first
} else {
last.next = LinkedListNode(value)
last = last.next
}
}
}
Finally the Sequence implementation
/// Sequence protocol adoption. It allows `for ... in` and a bunch of other methods too.
extension LinkedList: Sequence {
/// Iterator implementation
public class Iterator<T>: IteratorProtocol {
/// Maintain a ref to current element so next element can be reached
var cur: LinkedListNode<T>?
/// IteratorProtocol protocol requirement
public func next() -> T? {
let res = cur?.value
cur = cur?.next
return res
}
}
/// Sequence protocol requirement
public func makeIterator() -> Iterator<T> {
let g = LinkedList.Iterator()
g.cur = first
return g
}
}
Usage:
let linkedList = LinkedList<Int>()
linkedList.append(3)
linkedList.append(6)
linkedList.append(9)
linkedList.append(12)
for element in linkedList {
print(element)
}
let odds = linkedList.filter { return $0 % 2 == 0 }
print(odds)
The accepted answer is correct, and up until recently was the accepted way to address this. However, given the introduction of Protocol Extensions in Swift 2.0, rather than conformance to SequenceTypeand implementing func generate() -> GeneratorOf<Car> there is now an abstract base class that handles the implementation of this functionality for you called AnyGenerator<T> (see Apple docs) since GeneratorOf<T> no longer exists.
What this means is that you can simply subclass this abstract base class, and by doing do, inherit all of the functionality of the aforementioned protocol conformance:
class Cars: AnyGenerator<Car> {
private var carList = [Car]()
private var currentIndex:Int
...
}
One then need only override the next() method declared by the GeneratorType protocol (which AnyGenerator<T> also conforms to) in order to define the desired iteration behavior:
class Cars: AnyGenerator<Car> {
private var carList = [Car]()
private var currentIndex:Int
override func next() -> Car? {
if (currentIndex < self.carList.count) {
currentIndex++
return self.carList[currentIndex-1]
} else {
currentIndex = 0;
return nil
}
}
}