June 25, 2014

Swift, facades, and Objects with Collection Type Properties

Posted in iPhone development, mac development tagged , , , , at 7:26 pm by tetontech

Facade functions are very common in software. One of reason to use them is to put common code in a single function but have it behave differently without needing to pass one or more extra parameter indicating which behavior to execute. In Swift this can be problematic if we forget that Arrays, if passed to functions or methods, are copied if something is added to or removed from the passed Array.

Here is an example that separates negative numbers from zero and positive numbers. I have called the class DoesNotWork1 because it doesn’t work in Swift. The negativeInts and positiveInts arrays will always be empty. This is because the Arrays were passed to the _storeInt method.

import Foundation

class DoesNotWork1{
    var negativeInts:Array<Int> = Array<Int>()
    var positiveInts:Array<Int> = Array<Int>()
    
    func storeInt(an:Int){
        if an < 0{
            _storeInt(an, list:negativeInts)
        }
        else{
            _storeInt(an, list:positiveInts)
        }
    }
    func _storeInt(an:Int, var list:Array){
        list.append(an)
    }
}

 

OK … lets try another approach. It is less common that the previous example but is also frequently used. I have named this variation DoesNotWork2. This one doesn’t work for the same underlying reason that DoesNotWork1 fails. The Arrays are getting copied. Why? Because operators in Swift are functions. The arrays passed to the ternary operator ( ? : ) will be copied as soon as we try to modify their length.

import Foundation

class DoesNotWork2{
    var negativeInts:Array<Int> = Array<Int>()
    var positiveInts:Array<Int> = Array<Int>()
    
    func storeInt(an:Int){
        _storeInt(an, isNegative:an < 0)
    }
    func _storeInt(an:Int, isNegative:Bool){
        var list = isNegative ? negativeInts : positiveInts
        list.append(an)
    }
}

What then could a programmer do to create a facade that modifies specific arrays depending on the situation? I’ve called this example DoesWork. The difference is what happens in the ternary ( ? : ) operator. Instead of selecting and returning one of the class’s arrays it modifies them directly.

import Foundation

class DoesWork{
    var negativeInts:Array<Int> = Array<Int>()
    var positiveInts:Array<Int> = Array<Int>()
    
    func storeInt(an:Int){
        _storeInt(an, isNegative:an < 0)
    }
    func _storeInt(an:Int, isNegative:Bool){
        isNegative ? negativeInts.append(an) : positiveInts.append(an)
    }
}

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: