oyalhi
oyalhi

Reputation: 3994

Pass array pointer to another Class and keep a reference for future - Swift

I have successfully passed the array by reference. However, I want to keep the reference so that I can manage the array in another class.

Subclassing parse and using NSManaged as follows:

class User: PFUser {
    // MARK: Managed Properties
    @NSManaged private var pets: [Pet]

    // MARK: Properties
    private(set) lazy var petList: PetList = PetList(user: self, pets: &self.pets)

    // non-essentials are omitted
}

And the PetList class:

class PetList {
    private         var owner: User
    private(set)    var pets: [Pet]

    init(user: User, inout pets: [Pet]) {
        self.owner = user
        self.pets = pets
    }

    func appendPet(pet: Pet) {
        pet.owner = self.owner
        self.pets.append(pet)
    }

}

In the init function, I am trying to get the reference to the array. And from there I would like to modify the array in the PetList class (such as in appendPet.

How do I set a variable in the PetList class so that it points to an array in the User class.

Upvotes: 0

Views: 761

Answers (2)

Qbyte
Qbyte

Reputation: 13243

The simplest approach would be to make a computed property (if it should operate on the pets of the owner):

class PetList {
    private         var owner: User
    private(set)    var pets: [Pet] {
        get{ return owner.pets }
        set{ owner.pets = newValue }
    }

    init(user: User) {
        self.owner = user
    }

    func appendPet(pet: Pet) {
        pet.owner = self.owner
        self.pets.append(pet)
    }

}

But this could be slow for many pets because you set the pets of the owner every time you mutate the array.

Another approach would be to wrap the array in a class:

class ArrayWrapper<T> {
    var array: [T]
    init(_ array: [T]) {
        self.array = array
    }
}

And then use only the wrapper instead of the array:

class User: PFUser {
    // MARK: Managed Properties
    @NSManaged private var pets: ArrayWrapper<Pet>

    // MARK: Properties
    private(set) lazy var petList: PetList = PetList(user: self, pets: self.pets)

    // non-essentials are omitted
}

class PetList {
    private         var owner: User
    private(set)    var pets: ArrayWrapper<Pet>

    init(user: User, pets: ArrayWrapper<Pet>) {
        self.owner = user
        self.pets = pets
    }

    func appendPet(pet: Pet) {
        pet.owner = self.owner
        // operate only though the wrapper with .array
        self.pets.array.append(pet)
    }

}

Sidenote: You probably should make the variable owner weak or unowned in order to avoid reference cycles.

Upvotes: 2

Wain
Wain

Reputation: 119031

The appropriate approach to solve your problem in swift is to use an extension to the class to add all of your Pet related functions to your User class.

Upvotes: 0

Related Questions