简体   繁体   中英

Swift 4 Array get reference

I ran into an issue with arrays in Swift. The problem is that it's a value type in Swift. I'm trying to find a workaround. Here is the code that I have:

class Object: Codable{
    var name : String?
}

var objects: Array<Object>?
objects = Array<Object>()
if var obj = objects { // <----- Creates a copy of array here
    let o = Object()
    o.name = "1"
    objects?.append(o)
    print(obj) //<----- this one is missing "o" object
    print(objects)
}

I cannot use NSMutableArray because I have an array inside another codable class.

What's everybody's experience on this one? If somebody can share a solutions for that.

Getting used to arrays as value types isn't too tough really. If i were you my version of the code would just look like this

var objects: Array<Object>?
objects = Array<Object>()
if var unwrappedObjs = objects {
    let o = Object()
    o.name = "1"
    unwrappedObjs.append(o)
    objects = unwrappedObjs
}

or alternatively maybe this:

var objects: Array<Object>?
objects = Array<Object>()
if objects != nil {
    let o = Object()
    o.name = "1"
    objects?.append(o)
}

Lastly you could always try making your own "ReferenceArray" class that wraps the array APIs and gives you reference semantics but that seems like overkill. Sooner rather than later, arrays as value types will seem natural to reason about.

bitwit already mentioned this to a point, but I think that your biggest mistake is simply not accepting the new object as the source. Unless it's important to retain the Array<Object>? you should replace it with the Array<Object> one.

var objects: Array<Object>?
objects = Array<Object>()

if var objects = objects { // <----- Creates a copy of array here
    let o = Object()
    o.name = "1"
    objects.append(o) // objects is now the non-optional one
    print(objects)
}

If it needs to be in the same scope, use guard :

var objects: Array<Object>?
objects = Array<Object>()

guard var objects = objects else { // <----- Creates a copy of array here
    fatalError()
}

let o = Object()
o.name = "1"
objects.append(o) // objects is now the non-optional one
print(objects)

If you absolutely need an array to be referenced, you can make a container class:

public class ReferenceContainer<Element> {
    public var element: Element

    init(_ element: Element) {
        self.element = element
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM