RE: Core Data design patterns
RE: Core Data design patterns
- Subject: RE: Core Data design patterns
- From: Squ Aire <email@hidden>
- Date: Sun, 19 Jul 2009 20:59:22 +0000
- Importance: Normal
Thanks for these wonderful answer and tips.
I like how you have designed this stuff. Gladly, it is similar to what I've been doing. Based on this I can now refine my own stuff, e.g. by doing a subclass for each entity like you are doing.
Two more things though:
* About your error handling, how do you do it? My code differs in this respect, because in my CoreDataHelper I mentioned I have up until now had this handleError: method that takes in an NSError and whenever the error occurs, the model just calls this method and handles it internally. This means that I don't have to do any error handling in my Controller classes, making development easier. Does this, however, break any design principles? I may afford to do this because all my error handling did was to terminate the app using [NSApp terminate:self] and doing some NSLogs of the error information. (In fact, doing even that sometimes didn't terminate my application; how can I guarantee my app terminates? [NSApp terminate:self]; didn't seem to do the trick actually.) However, when you want to show some feedback at the UI level of errors, my method of handling errors in the model might not be such a good idea.
* Finally an unrelated and basic Core Data question: Where do you paste the code you copy using the "Copy Method Declarations/Implementations" feature in the data modeling tool? I really want to use those things because it is, according to docs, faster than valueForKey, setValueForKey, etc. Up until now, I have tended to make a subclass of each of my managed objects and pasted the declarations/implementations in there. Do you think this is a good idea?
--.
----------------------------------------
> From: email@hidden
> To: email@hidden
> Date: Sat, 18 Jul 2009 22:43:59 -0700
> Subject: Re: Core Data design patterns
>
>
> On 2009 Jul 17, at 09:26, Squ Aire wrote:
>
>> Throughout my application I have to do fetching. I have simplified
>> my code by making a helper class called CoreDataHelper...
>
>> In fact, I can think of another variation of my method. Namely, to
>> not have class methods in CoreDataHelper, but rather instance
>> methods and initialize the CoreDataHelper with the MOC. The
>> advantage of this would be that I would not have to pass the MOC
>> into each method call. The drawback is that I have to create a
>> CoreDataHelper instance each time I want to use its methods.
>
> This is what I've done, except I've taken it a step further. I've
> created helpers like this for several different entities. Each entity
> is a subclass of SSYMojo. SSYMojo has a moc and an entity. See my
> @interface for SSYMojo below.
>
>> A third variation would be to simply do either of the two variations
>> above, but not pass in MOC anywhere and instead just use [[NSApp
>> delegate] managedObjectContext] whenever I need it within
>> CoreDataHelper.
>
> I don't think you want to do that because all ^real^ Core Data apps,
> sooner or later, end up having multiple mocs.
>
>> A more general closing question: How do you make your code more
>> organized? ... Any antidotes?
>
> I believe you mean anecdotes.
>
> To avoid disorganized code, sit down with a pencil and big piece of
> paper, or a diagramming tool like OmniOutliner, and draw some class
> diagrams and flow charts. I've heard that some people even do this
> before they start on a project :)) The Holy Grail is to write a
> software specification which lays out everything so perfectly that you
> can hand it to a chimpanzee to write the code. In practice, there's
> always alot of back-and-forth between the spec and the code, and in
> the interest of getting the job done before the market moves on,
> you'll tend to write specs and diagrams for the more difficult parts,
> but "just write code" for the easy parts that you've had prior
> experience with. It's always a tradeoff between spending the time up
> front to plan and diagram, versus the risk of having to go back and do
> it later and rewrite code if your intuition turned out to be
> insufficient.
>
>> Maybe reading some good design principles book will help?
>
> Great.
>
>> Or getting a degree in CS?
>
> Wonderful if you've got the time.
>
>> How did you guys learn this stuff?
>
> The hard way, except it's not "learn", it's "learning" ;)
>
>
> ---------------------------------------
>
> #import
> #import "SSYErrorHandler.h"
>
>
> /*!
> @brief A class for putting and fetching -- "managing" -- managed
> objects of
> a particular entity in a particular managed object context.
>
> @details I wanted to make this a subclass of
> NSManagedObjectContext. However,
> the documentation for NSManagedObjectContext says that "you are highly
> discouraged from subclassing" it. So, what I did instead was to
> make this class
> be a wrapper around an managed object context which is an instance
> variable.
> */
> @interface SSYMojo : NSObject {
> NSManagedObjectContext* managedObjectContext ;
> NSString* entityName ;
> NSObject * errorHandler ;
> }
>
> /*!
> @brief The built-in managed object context which the receiver
> will use.
> */
> @property (retain) NSManagedObjectContext* managedObjectContext ;
>
> /*!
> @brief The name of the entity of the managed objects which the
> receiver is expected to manage.
> */
> @property (copy) NSString* entityName ;
>
> /*!
> @brief The object to which a setError:message will be sent if an
> error occurs.
> A weak reference. Be careful!
> */
> @property (assign) NSObject * errorHandler ;
>
> /*!
> @brief Designated Initializer for Mojo instances
>
> @details managedObjectContext and entityName are required. If
> either is nil, this
> method will return nil.
> @param managedObjectContext The managed object context into
> which objects
> will be managed.
> @param entityName The name of the entity of the objects which
> will be managed.
> @result The receiver, or nil if something failed.
> */
> - (id)initWithManagedObjectContext:
> (NSManagedObjectContext*)managedObjectContext_
> entityName:(NSString*)entityName_
> errorHandler:(NSObject *)
> errorHandler_ ;
>
>
> /*!
> @brief Returns all objects in the receiver's managed object context
> satisfying given predicates, if any, compounded OR or AND.
> @param subpredicates The array of subpredicates to be compounded
> @param type Either NSAndPredicateType or NSOrPredicateType
> @result An array of results, or an empty array if no results are
> found
> */
> - (NSArray*)objectsWithSubpredicates:(NSArray*)subpredicates
> type:(NSCompoundPredicateType)type ;
>
> /*!
> @brief Gets all of the objects in the receiver's managed object
> context
> satisfying a given predicate, if any.
>
> @details Pass predicate = nil to get all objects related to this
> extore.
> @param predicate The predicate required of results, or nil.
> @result An array of results, or an empty array if no results are
> found
> */
> - (NSArray*)objectsWithPredicate:(NSPredicate*)predicate ;
>
> /*!
> @brief Same as -objectsWithPredicate, but only returns the first
> item found
>
> @details Returns nil if no results are found
> */
> - (NSManagedObject*)objectWithPredicate:(NSPredicate*)predicate ;
>
> /*!
> @brief Returns all objects satisfying a predicate created
> "directly in code"
> */
> - (NSArray*)objectsWithDirectPredicateLeftExpression:(NSExpression*)lhs
> rightExpression:(NSExpression*)rhs
> operatorType:
> (NSPredicateOperatorType)operatorType ;
>
> /*!
> @brief Returns the first object satisfying a predicate created
> "directly in code"
> */
> - (NSManagedObject*)objectWithDirectPredicateLeftExpression:
> (NSExpression*)lhs
> rightExpression:(NSExpression*)rhs
> operatorType:
> (NSPredicateOperatorType)operatorType ;
>
> /*!
> @brief Returns all objects of the receiver's entity in the
> receiver's
> managed object context.
> */
> - (NSArray*)allObjects ;
>
> /*!
> @brief Counts all objects of the receiver's entity in the
> receiver's
> managed object context.
> */
> - (NSInteger)count ;
>
> /*!
> @brief Inserts a new object with the receiver's entityName into the
> receiver's managed object context
> @result The newly-inserted object
> */
> - (NSManagedObject*)newObject ;
>
> /*!
> @brief Returns the object from the receiver's managed object
> context
> that has a given object identifier.
> */
> - (NSManagedObject*)objectWithID:(NSManagedObjectID*)objectID ;
>
> /*!
> @brief Inserts an object from the receiver's managed object context
> */
> - (void)insertObject:(NSManagedObject*)object ;
>
> /*!
> @brief Deletes an object from the receiver's managed object context
> */
> - (void)deleteObject:(NSManagedObject*)object ;
>
> /*!
> @brief Deletes all objects of the receiver's entity from the
> receiver's
> managed object context
> */
> - (void)deleteAllObjects ;
>
> @end
>
> _______________________________________________
>
> 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
_________________________________________________________________
With Windows Live, you can organize, edit, and share your photos.
http://www.microsoft.com/middleeast/windows/windowslive/products/photo-gallery-edit.aspx_______________________________________________
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