1

I've essentially got two methods:

private func addBagToCollection(bag : VendorBag){
    var array = arrayForService(bag.type)
    array.append(bag)
}

And

func arrayForService(type : BAG_TYPE) -> Array<VendorBag>{
        switch type{
        case .bagTypeDryCleaning:
            return dcBags
        case .bagTypeWashAndFold:
            return wfBags
        case .bagTypeLaunderedShirt:
            return lsBags
        case .bagTypeHangDry:
            return hdBags
        case .bagTypeUnknown:
            return unBags
        }
    }

The issue is that the array being referenced in addBagToCollection isn't saving the appended items, meaning that every time that I call the method, the size of the array is 0.

I initialize all my arrays at the top of the class:

var hdBags : Array<VendorBag> = [VendorBag]()
var wfBags : Array<VendorBag> = [VendorBag]()
var lsBags : Array<VendorBag> = [VendorBag]()
var dcBags : Array<VendorBag> = [VendorBag]()
var unBags : Array<VendorBag> = [VendorBag]()

but for some reason, the arrayForService function seems to either only return a copy of the array, or a newly initialized one. How do I return a reference to that array so that all changes made to it are kept even after exiting the function?

Got some more info:

So indeed it seems like arrays are copied when returned from functions--

Swift’s Array types are implemented as structures. This means that arrays 
are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.

So how do I return a reference to the actual array rather than a copy of it?

Thanks!

0

1 Answer 1

4

Unlike NSArray class, Swift arrays are struct types which means they are copied when they are passed into functions.

From docs:

Note

Structures are always copied when they are passed around in your code, and do not use reference counting.

You need to use inout keyword if you want your array to be passed by reference, not by copy:

private func addBagToCollection(inout array: Array<VendorBag>, bag: VendorBag) {
  array.append(bag)
}

You can call that function as follows:

addBagToCollection(&arrayForService(bag.type), bag)
Sign up to request clarification or add additional context in comments.

12 Comments

That doesn't work (getting an error) - "Cannot convert value of type 'Array<VendorBag>' to expected argument type 'inout Array<VendorBag>'. This is most likely a result of the 'arrayForService' method returning a copy of an array and not an actual reference to any of the bag arrays. Try it yourself and see!
@royherma You can take a look at my code here: swiftstub.com/364381280. Error happens because of a missing &. Add that and you'll be good to go.
Your code is executing something very different than mine and achieving similar results coincidentally..Imagine you have several arrays of users (usersA, userB, etc...), and the arrayForService(arg) returns an array based on the arg. You then want to append a bag to the array that was returned from that method. I tested your code in my implem and it still doesnt work, because arrayForService returns a copy, and a reference to a copy is a copy so still no good :(
@royherma it doesn't have anything to do with arrayForService returning copy of an array. Frankly, it doesn't even return a copy of an array that you defined as instance variable. You probably are doing something wrong at some point of your code that is not shared with us.
In here, var array = arrayForService(bag.type), array here is the copy of the array that is returned from arrayForService because you initialized it with var keyword if that's what you are asking.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.