CoreData model design: Is excessive use of NSFetchRequest a symptom of a poorly designed model?
Core Data objects can be retrieved by using an NSFetchRequest
or by following relationships with other objects in the graph. Is it fair to say that in a well designed model will contain sufficient relationships (and fetched properties) such that the use of NSFetchRequests
are kept to a minimum?
The counter argument is that in iOS there exists NSFetchedRequestController
. Presumably if Apple believed that relationships and fetched properties provided satisf开发者_如何转开发actory performance with the existing faulting/caching they would not have created NSFetchedRequestController
.
There are instances when using an NSFetchRequest
are superior as Core Data can do all the work within SQLite. An example would be fetching aggregate values.
Any thoughts on this? I've had a look at the Core Data Programming Guide. There's relevant advice in the 'Fetching Managed Objects' and 'Core Data Performance' sections, but nothing to strongly suggest relationships over fetch requests or vice versa.
I would say that relationships and NSFetchRequest each have their strengths and weaknesses. As a developer you should know when it is appropriate to use one or the other. For example take this model:
-------------- 1 * ------------
| Department |<------------->>| Employee |
-------------- ------------
| name | | name |
-------------- | age |
| salary |
------------
If you want to retrieve all the employees belonging to a particular department then it is appropriate to follow the relationship 'department.employees'. It is not appropriate to create an NSFetchRequest for the Employee entity with predicate 'department == xxxx'.
Conversely, if you want to find employees for a particular department with a salary > x then it is appropriate to use an NSFetchRequest with a predicate like 'department == xxxxx AND salary > x'. It is not appropriate to retrieve all the employees using the department.employees relationship and then iterate over them in a loop to find the high-earners.
In summary, relationships or NSFetchRequests are not inherently 'good' or 'bad'. Just use them appropriately. Use relationships to navigate your object graph. Use NSFetchRequest to perform subset searches or where you need the flexibility of returning results as dictionaries or need to use NSExpressions.
EDIT TO ADD:
A lot of NSFetchRequests littered all over your code is a sign of bad design. I always encapsulate data requests in custom NSManagedObject classes and try not to have any Core Data calls in view/view controller code.
Fetched properties are, I suppose, a way of achieving the same thing. I prefer to create an NSFetchRequest in code rather than use the Core Data editor to do it. It is far more flexible but both ways amount to the same thing really.
The general rule of thumb is that the simpler the data model the better fetches work while the more complex the data model the better relationships work.
For example, if your data model has a single entity with no relationships then a fetch will work best to find the isolated managed objects. If you have a data model with a dozen entities all with two or more relationships, then you will use relationships heavily.
When you design a model in coredata you should keep in mind that if you have 1, 2 or n relations in the mode,l that's Indicate that your object graph will behave as SQL database would because it will only fetch the main rows, except your app explicit need in the first request all the objects. In fact Apple encourage split your model across relations for performance reasons, so when your model fault on a fetch in that moment will fetch the rest. The only aspect you should care about its the delete rules ( null, cascade..) because a bad designed delete rule may crash or affect performance. Trust me, I've never see nothing so efficient as core data. Make a strong model and core data will do the rest.
One of my apps (Mariette) use core data and another (billingfiles) use SQL
精彩评论