Skip to content

Instantly share code, notes, and snippets.

@robertmryan
Last active January 22, 2021 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertmryan/d0b9a666b51af3cc599df5b98c7eac4f to your computer and use it in GitHub Desktop.
Save robertmryan/d0b9a666b51af3cc599df5b98c7eac4f to your computer and use it in GitHub Desktop.
public class B {
private var lock = NSLock()
private var a: A? = nil
public func setA() {
lock.synchronized {
a = A(0)
}
}
public func hasA() -> Bool {
return lock.synchronized {
a != nil
}
}
public func resetA() {
lock.synchronized {
guard a != nil else { return }
a = A(1)
}
}
}
// using
extension NSLocking {
func synchronized<T>(block: () throws -> T) rethrows -> T {
lock()
defer { unlock() }
return try block()
}
}
@robertmryan
Copy link
Author

robertmryan commented Jan 22, 2021

I personally would avoid confusing names like setA and use computed property that does the synchronization:

public class B {
    private var lock = NSLock()
    private var _a: A? = nil

    public var a: A? {
        get { lock.synchronized { _a } }
        set { lock.synchronized { _a = newValue } }
    }

    public var hasA: Bool {
        lock.synchronized { _a != nil }
    }

    public func resetA() {
        lock.synchronized {
            guard _a != nil else { return }
            _a = A(1)
        }
    }
}

@alexcohn
Copy link

Nice point. The trick is I don't want a setter for a, so a public property is not applicable.

@robertmryan
Copy link
Author

Yeah, I figured that might be the case, which is why I posted it as a comment and not as the gist itself. I wasn't sure what to make of your setA method (which, because the set prefix is used in so many languages as a setter for a property, it was a bit unclear what the ultimate intent was)...

@alexcohn
Copy link

Sorry, this was a typo: I don't want a getter for a. I do expose a setter. The content of a is private to B, which has its internal logic of updating it (every n seconds). The external observer should only know whether a is enabled. It's fine if two external requests to set a collide and one of these (randomly) prevails: such setter does not care which value of a it replaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment