Re: Bindings and object-pointer keys
Re: Bindings and object-pointer keys
- Subject: Re: Bindings and object-pointer keys
- From: Ken Thomases <email@hidden>
- Date: Mon, 31 Dec 2007 02:18:06 -0600
On Dec 30, 2007, at 10:40 AM, Seth Pellegrino wrote:
In the main interface, there are two table views, both controlled
by instances of NSArrayController. One shows employees, the other
displays jobs. The employees table view has three columns, name
(bound to arrangedObjects.name), title (arrangedObjects.job.title),
and salary (arrangedObjects.job). The salary column uses a custom
'SalaryCell' which extracts a job's salary from a Job instance
(hence the unusual binding). In some "future version," this will be
necessary so the SalaryCell can draw itself differently to indicate
different jobs.
Phew, time to discuss the actual problem. Simply put, changes made
to salaries in the job table are not reflected in the employees
table without a forced refresh. To see this, simply create ('Hire')
a person, use the pop up menu to set their job, and then try to
change their salary. The salary column won't update until the next
time the employees table becomes key.
The reason for this problem is also rather simple -- technically,
the person's job property (to which the 'salary' table column is
bound) doesn't change. It's still a pointer to the exact same
memory location. However, the object at the other end of that
pointer has changed. Is there some way to make the bindings
mechanism aware of that fact? The options I see are a) somehow
track that changes have been made to a job object and then
programmatically force the table to refresh, or b) just throw up my
hands and switch to using Core Data.
Is there a more elegant solution I'm missing? Failing that, which
of the above options would you recommend?
There may be a more elegant or correct solution, but the following
should work:
Create a "synthetic" property on the Job class, let's call it
salaryData. Use setKeys:triggerChangeNotificationsForDependentKey:
to make the salaryData property dependent on the salary key (and any
other keys/properties on which SalaryCell bases its display and
behavior). Then, bind your salary column to the salaryData property.
So, what should the salaryData getter return? As a first pass,
perhaps just 'self' -- the Job instance, itself. In the future,
though, you might want to return some value object (e.g. a
dictionary) which really represents the inputs for the SalaryCell.
The theory here is that the SalaryCell doesn't really depend on the
whole job nor its identity. In all probability, in a real-world
application, a Job will have many properties, some of them relevant
to the appearance and behavior of a SalaryCell, but most not. In
that case, you really don't want the SalaryCell to update itself
every time _any_ property of a Job is changed. It should really be
bound to the specific aspects of a Job which are really relevant.
So, SalaryCell should not be bound to the job instance, but to the
property(ies) which are really relevant.
Put another way, I think both the existence of SalaryCell and your
struggles to get bindings to do what you want are hints that you need
another class. There should be a value-object class, perhaps Salary,
which aggregates the data relevant to representing salaries. Your
description of SalaryCell makes it clear that a simple number isn't
sufficient; otherwise, you'd just bind SalaryCell to
arrangedObject.job.salary. So, whatever is the thing which a
SalaryCell really represents, that's the contents of a Salary object.
You might be thinking that a Salary object is what your Job object
already was. The difference is that a Job is an entity. Its
identity is significant, and multiple Person objects share Job
objects. A Salary is a value object. So, maybe it will end up being
the case that a Job is a thin shell around a Salary. That's fine if
that's what is needed. That way, multiple Person objects may all
refer to a single Job, but when the Job's Salary is changed, that's
done in a proper KVO-conforming way (for example, using -[Job
setSalary:]).
I hope that helps.
Cheers,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden