Re: NSManagedObjectContextObjectsDidChangeNotification
Re: NSManagedObjectContextObjectsDidChangeNotification
- Subject: Re: NSManagedObjectContextObjectsDidChangeNotification
- From: Jerry Krinock <email@hidden>
- Date: Fri, 14 Nov 2008 19:26:56 -0800
On 2008 Nov, 14, at 18:25, Jim Correia wrote:
That's hard to answer without knowing a bit more about what it is
you are doing in response to the notification.
(For example, it might be that there is a more appropriate solution
to the problem you are trying to solve.)
Thank you, Jim. Indeed that's a good question. So I've conjured up
an easy-to-understand example:
I have an NSPersistentDocument representing a branch of a Public
Library. Its managed object context contains objects of class/entity
Book. Each Book has, among other attributes, an ISBN.
I sometimes need to know about duplicate books. But most of the
changes are just rearranging books on the shelves, and enumerating
through all books looking for a duplicate is expensive. So instead, I
observe NSManagedObjectContextObjectsDidChangeNotification for any
change that is either insertion or deletion of a Book, or a change to
the ISBN attribute of a Book. When such a change occurs, I set a flag
indicating that either a new duplicate may be present, or a duplicate
may have gone away.
But an NSPersistentDocument only has one managed object context. So,
along with the Books, this managed object context also contains a
Configuration object which contains hours of operation, etc. and a
Staff object which contains Employees, etc.
So, you see the first thing I need to do when I receive a
NSManagedObjectContextObjectsDidChangeNotification is to enumerate
through userInfo's insertedObjects and updatedObjects, and segregate
out those objects which are of class/entity Book.
Similarly I might be watching the 'salary' attributes of Employee
objects to determine, for example, if the Library might be over budget.
Since I wrote the original post I've completed and partially tested
the necessary code and pasted it in below. It's not horrendous, but
it just seems odd to me that
NSManagedObjectContextObjectsDidChangeNotification does not provide -
userInfo in a more immediately useful package.
Jerry
/******** NSArray+Segregate.h
#import <Cocoa/Cocoa.h>
@interface NSArray (Segregate)
/*!
@brief Copies each element of the receiver into an array containing
other elements of the same class and assembles the resulting arrays
into a dictionary.
@detail The keys in the dictionary are strings, class names obtained
by using NSStringFromClass().
This method is designed so that it may be invoked in succession upon
different arrays with the same dictionary argument. In
the end, the dictionary will contain one key/value pair for each
class of object found in all of the receiver arrays.
@param dic A mutable dictionary to which the segregated objects
will
be added.
*/
- (void)segregateByClassIntoDictionary:(NSMutableDictionary*)dic ;
@end
/******** NSArray+Segregate.m
#import "NSArray+Segregate.h"
@implementation NSArray (Segregate)
- (void)segregateByClassIntoDictionary:(NSMutableDictionary*)dic {
for (id object in self) {
Class class = [object class] ;
// Since a Class is not an object and does not conform to
NSCopying,
// we cannot use it as a key.
NSString* key = NSStringFromClass(class) ;
NSMutableArray* bin = [dic objectForKey:key] ;
if (!bin) {
bin = [[NSMutableArray alloc] init] ;
[dic setObject:bin
forKey:key] ;
[bin release] ;
}
[bin addObject:object] ;
}
}
@end
/******** SomeOtherFile.m
<snip>
// Send NSManagedObjectContextObjectsDidChangeNotifications to this
selector:
- (void)modelChanged:(NSNotification*)notification {
NSArray* insertedObjects = [[notification userInfo]
objectForKey:NSInsertedObjectsKey] ;
NSArray* deletedObjects = [[notification userInfo]
objectForKey:NSDeletedObjectsKey] ;
NSArray* updatedObjects = [[notification userInfo]
objectForKey:NSUpdatedObjectsKey] ;
NSMutableDictionary* objectsByClass = [[NSMutableDictionary
alloc] init] ;
[insertedObjects segregateByClassIntoDictionary:objectsByClass] ;
[deletedObjects segregateByClassIntoDictionary:objectsByClass] ;
[updatedObjects segregateByClassIntoDictionary:objectsByClass] ;
for (NSString* className in objectsByClass) {
if ([className isEqualToString:@"Book" {
....
}
else if ([className isEqualToString:@"Employee" {
....
}
<snip>
_______________________________________________
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