How to implement (bindable) access to array entries in Core Data?
How to implement (bindable) access to array entries in Core Data?
- Subject: How to implement (bindable) access to array entries in Core Data?
- From: Kaspar Fischer <email@hidden>
- Date: Sun, 7 Aug 2005 19:18:18 +0200
[Sorry for the length of this question, I first tried to post
a shortened version but it lacked motivation...]
Dear all,
My application sets up part of the user interface dynamically.
In particular, I need to programatically bind the value of
a pop-up menu to an entry of an array. As outlined below,
I want to do this using a proxy element, but I do not know how.
The relevant part of my Core Data model models a "questionary",
i.e., the user can first define a set of questions (each
question having a set of possible answers, which the user
predefines), and afterwards she can create "interviews", each
such interview contains answers to the previously defined
questionary.
For instance, the user could define the questionary consisting
of the two questions "Gender:" and "Hobby:" with answers
{"Male","Female"} and {"None","Football","Dancing"}. An interview
would be something like ("Male","Football"). This is the
idea. I modelled this in CoreData and now need to set
up the user interface for an interview: I want to display
a pop-up menu for each question and bind it appropriately.
The relevant part of my CoreData model looks as follows:
questions possibleAnswers
----------------> ----------->
Project Question Value
<---------------- <------------
enclosingProject enclosingQuestion
So far, there are three entities, Project, Question, and Value.
Project has a relationship 'questions' that links to entity Question
and an inverse relationship 'enclosingProject. Question has a
relationship 'possibleAnswers ' with inverse 'enclosingQuestion'.
In addition, each instance of Question has a unique attribute 'name'
(in my example above this would be "Gender:" or "Hobby:", respectively).
Moreover, there is an entity Interview:
answers chosenValue
--------------> ------------>
Interview Answer Value
<-------------- <------------
enclosingInterview answersUsingThisValue
In my example, the 'answers' relationship of each interview
would link to two Answer instances, one for the question
"Gender:", one for the question "Hobby:".
Finally, here is my problem: For the GUI of the interview window
I want to display a pop-up menu for each question and bind it
appropriately. In my example I need two pop-up menus (for gender
and hobby), and the "selectedObject" of each will be bound
to the chosenValue of the respective Answer instance in the
relation answers. Since I do not know how to bind to an element
of an array, I bind "selectedObject" to a controller for entity
Interview with key-path
"selection.answersProxy.Gender.chosenValue"
(and "selection.answersProxy.Hobby.chosenValue" for the other pop-up).
For this to work, I implemented a class AnswersProxy and added
to class Interview the routine
- (AnswersProxy *)answersProxy;
which simply returns a proxy object that finds the appropriate
entry in the array 'answers'. The question is: how can I implement
this proxy?
My current approach is more or less:
@implementation AnswersProxy
- (Answer *)getAnswerFromKey:(NSString *)key
{
// get answers:
NSArray *answers = [[_parent valueForKey:_parentKey]
allObjects]; (**)
// find the respective attribute:
int i, count = [answers count];
for (i=0; i<count; ++i) {
Answer *answer = [answers objectAtIndex:i];
NSString *name = [answer name];
if ([key isEqualToString:name]) {
return answer;
}
}
NSAssert1(FALSE,@"Unknown name '%@'",key); // (*)
return nil;
}
- (id)valueForKey:(NSString *)key
{
return [self getAnswerFromKey];
}
@end
The problem with this is that if the user adds an interview
and then chooses "Undo", the application crashes with an assertion
violation at (*). Using the debugger I found out that in order
to perform the undo, CoreData calls AnswersProxy's valueForKey
many times, and at some point, the array 'answers' fetched at (**)
has size 0, which I do not understand.
(If I just remove (*) then the app crashes when I do "Redo":
*** Selector 'observeValueForKeyPath:ofObject:change:context:'
sent to dealloced instance 0x57073c0 of class
NSKeyValueObservationForwarder.)
So how does one implement a proxy like the one above needed
for binding GUI elements (pop-up's in my case) to entries
of arrays?
I would be very glad for any help; I have spent the whole
weekend tracking down what CoreData does without success.
Kaspar
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden