0

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.

2
  • Why do you want to do that? Why not just add the function to the User? Commented Jul 19, 2015 at 9:20
  • I can. I started out that way actually. However, the User class had so many Pet related operations, add, remove, append, etc. I just wanted to separate those in to another class called PetList for managing the pets. Commented Jul 19, 2015 at 9:22

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Classes are passed by reference which solves the problem. I just didnt't know how to wrap the array in a class. I still have to study your code to really understand and learn - good example - thank you. Which variable are you referring to (to make it owner weakor unowned, petList?
Actually you should make both variables of PetList (owner, pets) weak or unowned since User references to PetList which is kind of a delegate for it. PS: If this answer answers your question you should mark it appropriately.
0

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.

1 Comment

Thank you for your reply. I don't agree with your answer though, as you suggest one design which I prefer another. I am trying to separate the Pet, PetList and User classes for a better and simpler design. I don't think there is an automatic 'appropriate' approach. Though I agree that it would be much simpler to code all this in a single class using an extension.

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.