• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bindings and object-pointer keys
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


References: 
 >Bindings and object-pointer keys (From: Seth Pellegrino <email@hidden>)

  • Prev by Date: Re: cocoa bindings NSTableColumn to @allKeys?
  • Next by Date: QTMovieView disabled
  • Previous by thread: Re: Bindings and object-pointer keys
  • Next by thread: Media Browser for iPhoto, iTunes, etc.
  • Index(es):
    • Date
    • Thread