0

Screenshot of the NSManagedObject subclasses I have created NSManagedObject subclasses

Im trying to copy a Cycle and all the TrainingWeeks, TrainingSessions and sets it contains. This cycle copying method I have created should in theory work but the cycle it returns contains a trainingWeek which itself contains trainingWeeks as well which causes a type casting error when its trying to cast TrainingWeek to TrainingSession. I can't figure out why?

The Cycle I'm copying contains 1 TrainingWeek in its ttoContainer, the TrainingWeek contains 1 TrainingSesison in its ttoContainer, this TrainingSession contains 1 Set in its ttoContainer. All these objects subclass TrainingTimeObject and implements TTOCopyProtocol (A method that just creates a new obj of the same type and manually sets the attributes of that objects to the same of the old obj). All objects but Set implements TTOContainerProtocol (The obj has a ttoContainer).

Here is the code for the method:

 private func copyTTOandContainer(obj: TrainingTimeObject) -> TrainingTimeObject? {
        
        // cast as conforming to ttoCopyProtocol
        guard let obj: TTOCopyProtocol = obj as? TTOCopyProtocol else {return nil}
        
        // Create a copy of the obj
        let objCopy = obj.ttoCopy()
        
        // cast as tto with a container
        guard let objCopy = objCopy as? TTOContainerProtocol else {return objCopy}
        
        // get the container
        guard let objCopyTTOContainer = objCopy.ttoContainer else {return objCopy as? TrainingTimeObject}
        
        // cast the obj argument as conforming to TTOContainerProtocol
        guard let objContainer: TTOContainerProtocol = obj as? TTOContainerProtocol else {return objCopy as? TrainingTimeObject}
        
        // get container as array
        let objContainerAsArray: [TrainingTimeObject] = objContainer.ttoContainer!.getTTOContainerAsArray()
        
        // Iterate through container
        for tto in objContainerAsArray {
            
            // cast as copyable tto
            guard let tto: TTOCopyProtocol = tto as? TTOCopyProtocol else {continue}
            
            // copy the tto from the container
            let ttoCopy: TrainingTimeObject = tto.ttoCopy()
            
            // add the copy to the container of the obj copy
            objCopyTTOContainer.addToTTOContainer(tto: ttoCopy)
            
            // check if the sub tto copy contains a container, if so copy that aswell (Creates recursion loop until all obj in the data 'tree' are copied)
            guard let ttoCopyWithSubTTO: TrainingTimeObject = copyTTOandContainer(obj: tto) else {continue}
            
            // remove the old obj
            objCopyTTOContainer.removeFromTTOContainer(tto: ttoCopy)
            
            // add the new obj
            objCopyTTOContainer.addToTTOContainer(tto: ttoCopyWithSubTTO)
            
        }

        return objCopy as? TrainingTimeObject
    }

What I tried:

  • Rewriting the method, expected this to catch any human error with the code, resulted in the same result.
  • I stepped through the code expecting the method to create a TrainingWeek in the TrainingWeek, noted that it actually doesn't and that it does what it is supposed to do confusing me further on how the return becomes wrong?
  • Went through all the ttoCopy() implementations and Constructors, expected the entity description to be wrong somewhere, it wasn't, its all correct.
willaayy
  • 1
  • 3
  • https://stackoverflow.com/questions/2998613/how-do-i-copy-or-move-an-nsmanagedobject-from-one-context-to-another – matt Aug 13 '23 at 13:11
  • What is the benefit in practice of this – frankly confusing – code? – vadian Aug 13 '23 at 14:45
  • @vadian benefit over what? And why is it confusing? Please elaborate, this is my first project working with core data? – willaayy Aug 13 '23 at 15:09
  • Confusing are the cryptic snake_case names like `sub_tto_copy_w_container`. And benefit means purpose/goal. And what is `ttoCopy()` and `TTOCopyProtocol`? – vadian Aug 13 '23 at 15:25
  • @vadian, yeah those variable names probably need some work, sub_tto_copy_w_container means it is a training time object from within another training time object that has a training time container. ttoCopy() is the method that needs to be implemented from the TTOCopyProtocol I made, this is just a method that creates an object of the same class as the implementing class and copies the attribute values. The goal is to be able to copy a TrainingTimeObject and all the TrainingTimeObjects it contains. You can see the screenshot I provided, that might clear some things up. – willaayy Aug 13 '23 at 16:51
  • @vadian I edited the code so it has the correct case and tried to make It more readable, should be up soon. – willaayy Aug 13 '23 at 17:15
  • It’s almost impossible for an outsider to fully understand the code with the protocols and the superclass and all the casting that is going on. What I wonder is why you even need protocols in the first place and if the code had been clearer if you had worked with the real types instead. – Joakim Danielson Aug 14 '23 at 06:51
  • Where exactly do you get the typecasting error that you mention? – Tom Harrington Aug 14 '23 at 16:07
  • Also, you say *"I stepped through the code expecting the method to create a TrainingWeek in the TrainingWeek, noted that it actually doesn't..."*. What does happen? Does it create some other kind of object? Does it fail to create anything? What line of code does this happen on? – Tom Harrington Aug 14 '23 at 17:22
  • @TomHarrington, I expected the method to create a TrainingSession in the TrainingWeek but the TrainingWeek contains a TrainingWeek. The error happens when i try to cast the TrainingWeek ttoContainer content to TrainingSession. So the error appears when I do operations on the returning object. so it should be Cycle(TrainingWeek(TrainingSession(Set))) but it returns Cycle(TrainingWeek(TrainingWeek)) – willaayy Aug 19 '23 at 13:02
  • Please provide enough code so others can better understand or reproduce the problem. – Community Aug 20 '23 at 10:55

0 Answers0