views:

110

answers:

1

I've got a relatively complicated Core Data relationship structure and I'm trying to figure out how to set up value dependencies (or observations) across various to-many relationships. Let me start out with some basic info. I've got a classroom with students, assignments, and grades (students X assignments). For simplicity's sake, we don't really have to focus much on the assignments yet.

StudentObj <--->> ScoreObj <<---> AssignmentObj

Each ScoreObj has a to-one relation with the StudentObj and the AssignmentObj.

  • ScoreObj has real attributes for the numerical grade, the turnInDate, and notes.

AssignmentObj.scores is the set of Score objects for that assignment (N = all students).

  • AssignmentObj has real attributes for name, dueDate, curveFunction, gradeWeight, and maxPoints.

StudentObj.scores is the set of Score objects for that student (N = all assignments).

  • StudentObj also has real attributes like name, studentID, email, etc.
  • StudentObj has a transient (calculated, not stored) attribute called gradeTotal.

This last item, gradeTotal, is the real pickle. it calculates the student's overall semester grade using the scores (ScoreObj) from all their assignments, their associated assignment gradeWeights, curves, and maxPoints, and various other things.

This gradeTotal value is displayed in a table column, along with all the students and their individual assignment grades. Determining the value of gradeTotal is a relatively expensive operation, particularly with a large class, therefore I want to run it only when necessary. For simplicity's sake, I'm not storing that gradeTotal value in the core data model. I don't mind caching it somewhere, but I'm having a bitch of a time determining where and how to best update that cache.

I need to run that calculation for each student whenever any value changes that affects their gradeTotal. If this were a simple to-one relationship, I know I could use something like keyPathsForValuesAffectingGradeTotal ... but it's more like a many-to-one-to-many relationship. Does anyone know of an elegant (and KVC correct) solution? I guess I could tear through all those score and assignment objects and tell them to register their students as observers. But this seems like a blunt force approach.

+1  A: 

I just postet a project on github which probably solves part of the problem with observings

http://github.com/mbrugger/CoreDataDependentProperties

A more detailed description of the project can be found there.

-(NSArray*) keyPathsForValuesAffecting would not have solved your problem as this only works across to-one relations

In addition you should not make the dependent attribute transient, as it makes your context "dirty" (unsaved changes) already after recalculating all values after loading

Martin Brugger
I like this approach. Much more elegant than the rat's nest of observations that I previously implemented.
Greg Combs