About synchronized scope in Swift - objective-c

Objective-C:
#synchronized {
return;
}
NSLog(#"This line of code does not run.");
Objective-C's #synchronized is a language-level directive and does not introduce a new function scope.
Swift:
synchronized {
return
}
print("This line of code does run.")
func synchronized(lock: AnyObject, #noescape closure: () -> Void) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
Synchronized uses closures which do introduce a function scope.
Question:
Can I do the same in Swift? Does not introduce a new function scope.
Real Problem
public func stopRecording() {
synchronized(self) {
guard status == .Recording else { return }
status = .StoppingRecording
}
// Many somethings need to do, and I don`t want to write into the closure.
finishRecording()
......
......
......
}
Workaround:
if (synchronized(self) { return true }) {
return
}
print(#"This line of code does not run.")
func synchronized(lock: AnyObject, #noescape closure: () -> Bool) -> Bool {
objc_sync_enter(lock)
defer {
objc_sync_exit(lock)
}
return closure()
}
Someone has a elegant solution?

I just put together a solution that isn't too bad. We cannot introduce a custom language construct that doesn't introduce a new scope, therefore we need to use one of the existing ones. The if statement should work for that. I made a small class for that, which does but one thing: Lock the given object and check that the unlock method got called before it deallocates (along with some additions for debugging):
final class LockingManager {
let obj: AnyObject
let file: StaticString
let line: UInt
var locked = true
init(obj: AnyObject, file: StaticString, line: UInt) {
self.obj = obj
self.file = file
self.line = line
objc_sync_enter(obj)
}
func unlock() {
objc_sync_exit(obj)
locked = false
}
deinit {
precondition(!locked, "Object \(obj) not unlocked", file: file, line: line)
}
}
With a function like this:
func lock(obj: AnyObject, file: StaticString = #file, line: UInt = #line) -> (() -> Void)? {
return LockingManager(obj: obj, file: file, line: line).unlock
}
We can use it like this:
if let unlock = lock(obj: self) {
defer { unlock() }
// Do stuff
}
Since method never returns nil, you don't ever want an else part. Since the unlock method, which holds the only reference to the LockingManager, is only available within the if statement, after the statement the LockingManager gets deallocated. Upon deallocation, it checks whether the unlock method was called and if not, throws an error.
I understand that this isn't a super nice solution, but it does work in that it doesn't introduce a new scope (and additionally checks for correct usage).
Another solution would be to just use simple function calls and a do block:
do {
objc_sync_enter(self)
defer { objc_sync_exit(self) }
// Do stuff
}
I personally prefer the second approach (with some better named functions), because it's much clearer what it does.

Related

Actual type lost on call

Another question on polymorphism in Go, references: Embedding instead of inheritance in Go, https://medium.com/#adrianwit/abstract-class-reinvented-with-go-4a7326525034
Motivation: there is an interface (with some methods for dealing with "the outside world") and a bunch of implementation structs of that interface.
There is a "standard" implementation of some of these methods, where common logic should be put in one place with delegation to (new) methods in the structs-implementing-the-interface ("subclasses" is not a word).
I've read the medium link above and wrote some test code. Alas, it does not work the way I expect, the actual type of a struct is lost when the call on the interface is indirect.
In C++ this is called "based class slicing" and happens when passing a polymorphic class by value. In my Go test code I'm careful to pass by reference, and then Go is not C++ (or Java).
Code: https://play.golang.org/p/lxAmw8v_kiW
Inline:
package main
import (
"log"
"reflect"
"strings"
)
// Command - interface
type Command interface {
Execute()
getCommandString() string
onData(data string)
}
// Command - implementation
type Command_Impl struct {
commandString string
conn Connection
}
func newCommand_Impl(conn Connection, data string, args ...string) Command_Impl {
var buf strings.Builder
buf.WriteString(data)
for _, key := range args {
buf.WriteString(" ")
buf.WriteString(key)
}
return Command_Impl {
conn: conn,
commandString: buf.String(),
}
}
func (self *Command_Impl) Execute() {
log.Printf("Command Impl Execute: %s", reflect.TypeOf(self))
self.conn.execute(self)
}
func (self *Command_Impl) getCommandString() string {
return self.commandString
}
func (self *Command_Impl) onData(data string) {
log.Printf("Command Impl onData: %s", data)
}
// Command - subclass
type Command_Login struct {
Command_Impl
onDataCalled bool
}
func newCommand_Login(conn Connection) *Command_Login {
return &Command_Login{
Command_Impl: newCommand_Impl(conn, "LOGIN", "user#foo.com", "pa$$w0rd"),
}
}
func (self *Command_Login) onData(data string) {
log.Printf("Command Login onData: %s", data)
self.onDataCalled = true
}
// Connection - interface
type Connection interface {
execute(command Command)
}
// Connection - impelementation
type Connection_Impl struct {
}
func newConnection_Impl() *Connection_Impl {
return &Connection_Impl{}
}
func (self *Connection_Impl) execute(command Command) {
log.Printf("Connection execute: %s, %s", command.getCommandString(), reflect.TypeOf(command))
command.onData("some data")
}
func main() {
conn := newConnection_Impl()
command := newCommand_Login(conn)
// I expect command.Execute to preserve actual type of command all the way through
// command.conn.execute(self) and then the callback onData from connection to command
// to use the onData in Command_Login
//
// This does not happen however, the test fails
command.Execute()
// This does preserve actual type of command, but isn't how I'd like to connect
// commands and connections...
//
//conn.execute(command)
if command.onDataCalled {
log.Printf("*** GOOD: Command_Login onData ***was*** called")
} else {
log.Printf("*** ERROR: Command_Login onData ***not*** called")
}
}
There is a Command interface which defines some methods.
There is a Command_Impl struct where I'd like to implement some common code that would further delegate to finer-grained methods in more structs that implement the same interface ("subclass is not a word"), similar to:
https://stackoverflow.com/a/1727737/2342806
The question:
Calling command.Execute() which in turn calls conn.execute(self) ends up "slicing" the Command_Login object and inside Connection.execute it's turned into Command_Impl. As a result, onData interface method defined for Command_Login do not get called.
If I call conn.execute(command) then the right onData does get called, but this is not how I'd like to connect my objects (e.g. Command already has a Connection, but basically what I wrote above about reusing implementation).
In Go terms, I'm trying to come up with a way to delegate implementation by embedding, and have a way to for the delegate to call back into the enclosing type (which fine-tunes the delegate's logic).
Alas, it seems to not be supported by Go (at least I can't find a way) - once you delegate to an embedded struct, your calls stay entirely there in the embedded struct, it "does not know" that it's part of a larger object which may be wanting to override some of the embedded struct's methods.
What about delegating implementation by implementing the Execute interface at the shallowest depth you need?
func (self *Command_Login) Execute() {
self.Command_Impl.Execute()
log.Printf("Command Login Execute: %s", reflect.TypeOf(self))
self.onDataCalled = true
}
https://play.golang.org/p/HvaKHZWIO5W

Having a singleton use the value from initWithCoder instead of creating a new instance in Swift

I have a simple boolean variable in a function on which a set an observer to check when it changes:
var userValid: Bool{
didSet{
let valid=userValid ? "valid" : "not valid"
print("uservalid changed to \(valid)")
}
}
I set it to false in the init and then to true in the program: the initialiser is called twice once for the class and once for the subclass but I am alway checking the value in the class. So I am seeing the variable is set to true in the observer, but then when I check it in another function I find it at false without the observer to be ever called again.
As it comes out the problem seems to stem from the fact I initialise two times the class: once as a singleton and the other one with:
init?(coder aDecoder: NSCoder)
Of course I initialise the singleton with:
public class func sharedMapDelegate() -> MapDelegate {
struct Static {
static let instance : MapDelegate = MapDelegate()
}
return Static.instance
}
How may I return the value generated from the initWithCoder instead of creating a new one?
I think I have fixed it by changing the singleton to:
public class func sharedMapDelegate() -> MapDelegate {
struct Static {
static var instance : MapDelegate {
if let me = Factory.sharedFactory().mapHandler {
return me
} else {
Factory.sharedFactory().mapHandler=MapDelegate()
return Factory.sharedFactory().mapHandler
}
}
}
return Static.instance
}

Assigning a Delegate to NSOpenPanel in Nested Scope Causes EXC_BAD_ACCESS

Consider the following simplified code example. It's presented here in Swift, but the same behavior occurs in objective-c.
import Foundation
import Cocoa
class MainWindow : NSWindow {
#IBAction func onClick_openFile(sender : AnyObject?) {
let path = runOpenPanel(false);
NSLog(path as String)
}
#IBAction func onClick_crashyByeBye(sender : AnyObject?) {
let path = runOpenPanel(true);
NSLog(path as String)
}
private func runOpenPanel(useCrashyDelegate : Bool) -> NSString {
let openPanel = NSOpenPanel.init()
openPanel.canChooseDirectories = false
openPanel.canChooseFiles = true
openPanel.allowsMultipleSelection = false
let safeDelegate = MyOpenPanelDelegate.init() //same scope as openPanel.runModal()--works fine
if (useCrashyDelegate) {
let crashyDelegate = MyOpenPanelDelegate.init() //falls out of scope before openPanel.runModal() and crashes
openPanel.delegate = crashyDelegate
} else {
openPanel.delegate = safeDelegate
}
if (openPanel.runModal() == NSFileHandlingPanelOKButton && openPanel.URLs.count == 1) {
return openPanel.URLs[0].path!
}
return ""
}
}
class MyOpenPanelDelegate : NSObject, NSOpenSavePanelDelegate {
func panel(sender: AnyObject, shouldEnableURL url: NSURL) -> Bool {
var isDir : ObjCBool = false
if (NSFileManager.defaultManager().fileExistsAtPath(url.path!, isDirectory: &isDir)) {
return isDir || (url.path! as NSString).lastPathComponent.lowercaseString == "foo.txt"
}
return false
}
}
When the useCrashyDelegate argument to runOpenPanel is true, crashyDelegate is instantiated in a nested scope and falls out of scope before the call to openPanel.runModal(). Since the open panel assigns crashyDelegate as its delegate, I would expect crashyDelegate's reference count to be incremented. However, the application crashes with an EXC_BAD_ACCESS when useCrashyDelegate is true. If useCrashyDelegate is false, safeDelegate, which is instantiated in the same scope as the call to openPanel.runModal(), is assigned to the open panel and there is no EXC_BAD_ACCESS.
This is leading me to believe that NSOpenPanel is not incrementing its delegate's reference count. Is this the expected behavior, or might this be a bug?
This is leading me to believe that NSOpenPanel is not incrementing its delegate's reference count. Is this the expected behavior, or might this be a bug?
It is expected. Check the type of the property and you will see it is assign (Objective-C) or unsafe (Swift), a strong reference is not kept. This is a common design pattern for Cocoa delegates.
HTH

Simulating macros with return in Swift

In Obj-C, I could define a macro
#define check_nil(x) if (!x) { return nil }
which can be used to test whether a function has returned nil (indicating an error), and if that's the case, the caller can simply return nil -- propagating the error up the stack. I am writing a parser, and this pattern happens very often. E.g.
- (id)caller {
...
id z = [self callee];
check_nil(z);
...
}
- (id)callee {
...
}
Unfortunately, after moving to swift, macros are gone. Function (with #autoclosure) are to replace them, but not in this case. Now my code is littered with identical if checks.
Any idea to replicate the same thing in Swift?
You are not going to be able to implement that pattern exactly.
Perhaps you could use a type that will turn future operations into no-ops if they ever return nil:
struct NonNil<T> {
var cantBeNil: T?
mutating func update(withClosure: () -> T?) {
if self.cantBeNil != nil {
self.cantBeNil = withClosure()
}
}
}
Then you can use this struct like so:
func myFunc() -> String? {
var nonNil = NonNil(cantBeNil: "")
nonNil.update {
// some action
return "new value"
}
nonNil.update {
// another action that ends up returning nil
return nil
}
// The rest of these don't end up calling the closure
nonNil.update {
println("not called")
return ""
}
nonNil.update {
println("not called")
return ""
}
return nonNil.cantBeNil
}
The idea being that if any operation returns nil, the rest of the code will fall through until the return statement, not executing any additional operations.
This will also visually separate all of the parts of the code that can cause the value to be set to nil

Accessing items in UIDynamicItemBehavior with Optional return value

I want to rewrite this Objective-C method in Swift.
I'm trying to find the best way to do it.
- (UIDynamicItemBehavior*) itemBehaviourForView:(UIView*)view
{
for (UIDynamicItemBehavior* behaviour in _animator.behaviors)
{
if (behaviour.class == [UIDynamicItemBehavior class] && [behaviour.items firstObject] == view)
{
return behaviour;
}
}
return nil;
}
I wrote something like that:
func itemBehaviorForView(view :UIView)->UIDynamicItemBehavior
{
for dynamicItemBehavior in animator.behaviors
{
if dynamicItemBehavior is UIDynamicItemBehavior && dynamicItemBehavior.items.firstObject == view
{
return dynamicItemBehavior as UIDynamicItemBehavior
}
}
return nil
}
I see two problems:
dynamicItemBehavior.items.firstObject is not Array, so there is no firstObject method
I cannot return nil
What should I do about these?
If there is a possibility that the function will return nil then the function's return type needs to be an optional. In your case declare the function as:
func itemBehaviorForView (view:UIView) -> UIDynamicItemBehavior?
The documentation for UIDynamicItemBehavior declares items as an array with:
var items: [AnyObject]! { get }
and thus you would reference the first object using array subscript notation as:
dynamicItemBehavior.items[0]
Of course, the items might be empty. To handle that in idiomatic Swift use:
if dynamicItemBehavior is UIDynamicItemBehavior {
if let firstView = dynamicItemBehavior.items?[0] {
if firstView == view {
return dynamicItemBehavior as UIDynamicItemBehavior
}
}
}
where the use of if let <var> will bind <var> iff the result of ...items? is not nil.
More functional approach after conversion:
let r = (animator.behaviors.filter { $0 is UIDynamicItemBehavior } as [UIDynamicItemBehavior])
.filter({ $0.items?[0] === view })
return r.count > 0 ? r[0] : nil
And we can even shrink it to one line return if we bridgeToObjectiveC() the result to take advantage of firstObject property:
return (animator.behaviors.filter { $0 is UIDynamicItemBehavior } as [UIDynamicItemBehavior])
.filter({ $0.items?[0] === view }).bridgeToObjectiveC().firstObject as? UIDynamicItemBehavior
Remarks:
Objective-C == to compare references in Swift achieved with ===.
I know that initial Objective-C algorithm was eager and returned as soon as match found. Show the expressiveness of functional approach.
I think Keenle was on the right track with using a functional style. But this is not a job for filter, this is a job for find. It will stop early on the first match it encounters. Unfortunately Swift does not currently implement find for us (unlike filter), but we can add it with extensions!
Unlike the other answers here, I don't know the type of animator or behaviors. I'm going to assume that behaviors is an NSArray, if that assumption is incorrect, please let me know.
extension NSArray {
func find(predicate: (AnyObject) -> Bool) -> AnyObject? {
for element: AnyObject in self {
if predicate(element) {
return element
}
}
return nil
}
}
Now we just have to update your function to use this!
func itemBehaviorForView(view: UIView) -> UIDynamicItemBehavior?
{
func predicate(object: AnyObject) -> Bool {
if let dynamicItemBehavior = object as? UIDynamicItemBehavior {
return view === dynamicItemBehavior.items?[0]
}
return false
}
return animator.behaviors.find(predicate) as? UIDynamicItemBehavior
}
I will admit, the casting on the final return statement is a little bit ugly. If animator.behaviors was know to only contains objects of the acceptable return type we could avoid this, but you're likely stuck with this because of the obj-c code.