title: Detecting changes to a specific attribute of NSManagedObject
body: <p>How can I detect changes to a specific attribute of an <code>NSManagedObject</code>? In my Core Data data model, I have a <code>Product</code> entity that represents a product for sale. The <code>Product</code> entity has several attributes: <code>price</code>, <code>sku</code>, <code>weight</code>, <code>numberInStock</code>, etc. Whenever the <code>price</code> attribute of a <code>Product</code> changes, I need to perform a lengthy calculation. Consequently, I would like to know when the <code>price</code> attribute of <em>any</em> <code>Product</code> changes, <strong>[edit] even if that change comes from merging a context saved on another thread</strong>. What is a good way to go about doing this? I have thousands of <code>Product</code> objects in my store; obviously it's not feasible to send each one an <code>addObserver</code> message.</p>
  
  <p>I have been using <code>NSManagedObjectContextObjectsDidChangeNotification</code> to detect changes, but it only notifies me <em>that</em> a managed object has changed, not <em>which</em> attribute of that object has changed. I could redo the calculation whenever there's <em>any</em> change to a <code>Product</code>, but that results in useless recalculations whenever an irrelevant attribute has changed. I'm considering making a <code>Price</code> entity (that only contains a <code>price</code> attribute) and using a to-one relationship between <code>Product</code> and <code>Price</code>. This way, I can detect changes to <code>Price</code> objects in order to kick off the calculation. This seems excessively kludgy to me. Is there a better way?</p>
  
  <p><strong>Update:</strong></p>
  
  <p>@railwayparade pointed out that I could use the <code>changedValues</code> method of <code>NSManagedObject</code> to determine which properties have changed for each updated object. I completely missed that method, and it would totally solve my problem if the changes weren't being made on a background thread and merged into the main thread's context. (See next paragraph.)</p>
  
  <p>I completely missed a subtlety about the way that <code>NSManagedObjectContextObjectsDidChangeNotification</code> works. As far as I can tell, when a managed object context saved on another thread is merged into a context on the main thread (using a <code>mergeChangesFromContextDidSaveNotification:</code>), the resulting <code>NSManagedObjectContextObjectsDidChangeNotification</code> <em>only</em> contains change information about objects that are currently in the main thread's managed object context. If a changed object isn't in the main thread's context, it won't be part of the notification. It makes sense, but wasn't what I was anticipating. Therefore, my thought of using a to-one relationship instead of an attribute in order to get more detailed change information actually requires examination of the background thread's <code>NSManagedObjectContextDidSaveNotification</code>, not the main thread's <code>NSManagedObjectContextObjectsDidChangeNotification</code>. Of course, it would be much smarter to simply use the <code>changedValues</code> method of <code>NSManagedObject</code> as @railwayparade helpfully pointed out. However, I'm still left with the problem that the change notification from the merge on the main thread won't necessarily contain all of the changes made on the background thread.</p>