I dont understand how Breeze.EntityManager store the data? It stores it in local container called entity cache, but where is this stored? Is it local storage, session storage and is there any limit on entity data that can be stored?
The EntityManager cache is a private, in-memory data structure within an instance of the EntityManager itself.
There is no public API for touching it. The physical limit is the memory in your browser. The practical limit is less of course.
The EntityManager cache is transient. It has the lifetime of the EntityManager instance. Close the browser and kiss it good bye.
Related
I'm developing an app that similar to Instagram feed (tableviews with cells that contain images and some labels).
For all the data I'm getting from the database, I'm using Data Task (because it doesn't take much to receive them), but for the images (which their url's I get with the Data request), I need to save locally for future use (improve user experience).
My logic is the following:
Save in NSCache or in Document Directory, the images inside folder with the date they been downloaded(create it once and append all other images if needed) (I'm deleting every folder which is not from the recent 7 days), and then for the TableView, just load if from there, so the tableview will scroll smoothly and won't load the url directly from its delegate method.
So where is the better place to store them according to my needs, NSCache or Document Directory.
Looking forward to hearing your suggestions, Thank you!
NSCache and persistent storage serve largely different purposes. NSCache holds the item in memory and is used for optimal performance. But it takes up memory (RAM) and you really should make sure that if you use NSCache that you respond to memory warnings and purge the NSCache in those cases. And when the app terminates, the NSCache is lost.
Using persistent storage cache (generally the Caches folder) is used for a different purpose, saving you from needing to re-retrieve the asset via some network request, but not holding the resource in memory. This makes it a great cache mechanism across sessions of running the app or in situations where you may have encountered memory pressure, purged the NSCache, but didn't want to re-retrieve the asset from the network.
Note that I mention the Caches folder for persistent storage, whereas you seemed to presume that one would use Documents folder, but there are two considerations:
Apple is getting more particular about apps only using Documents folder for user data that cannot be easily recreated, and using Caches folder for data that is easily re-retrieved. See File System Basics for more information.
Starting with iOS 11, you should only store user visible documents in the Documents folder (see WWDC 2017 Fall video, iOS Storage Best Practices). Even if you had internally used files that were not easily reconstructed, unless the intent was to eventually expose the user to them, you'd use the Application Support directory, not the Documents folder.
Bottom line, one would generally use the Caches folder for a persistent storage based cache.
Note, we'll often use a two-tier cache mechanism. Cache the resource to both NSCache and the Caches folder. Then, when you go to retrieve a resource, first check NSCache (really fast), if not there, check persistent storage, and if not there, re-retrieve the asset from the network.
Having said all of that, to make it even more complicated, there is a third type of cache, that provided by NSURLCache (i.e. responses for network requests are transparently cached by NSURLSession and NSURLConnection). This cache is dictated by poorly documented rules (e.g. it won't cache any single item whose size exceeds 5% of the total cache size) and is subject to the HTTP headers provided by the network response. This cache, though, operates largely transparently to you and provides both memory and persistent storage caches. Often you can enjoy NSURLCache caching behavior with absolutely no intervention on your part. It's seamless (when it works).
We are thinking of using HttpRuntime.Cache for storing data accessed frequently by all users, but wanted to know what are the performance implications of using HttpRuntime.Cache? Are the contents of the cache transported in every http request and response? How much information can be reasonably stored in there?
What are the performance implications of using HttpRuntime.Cache?
Normally, Cache is stored in server's memory, unless server are configured as Web Farm or Web Garden. As the result, accessing to Cache is really fast compare is Database.
Are the contents of the cache transported in every http request and
response?
No.
How much information can be reasonably stored in there?
Virtually, there is no limit. However, you only want to cache the information - you often needed and do not change very often. In addition, you do not want to cache images and files - Cache is not meant for that.
Core Data has built-in caching mechanism and uses it automatically for object fetching and faulting-related operations, but I couldn't find any documents or articles about modifying this default caching behaviors.
Is there any way to increase or decrease Core Data's default cache?
I'm considering of making a kind of NSManagedObject container in order to reduce overheads of loading data from persistent store, but not sure it's a good idea or not.
As far as I know, CoreData does not expose any general API to control its caching behavior.
You can control the size of the object graph of a given context by using:
[context refreshObject:<obj> mergeChanges:NO];
or by reseting the context entirely:
[context reset];
See here for more information.
This might also be of interest.
The container you plan to build sounds like the NSPersistentStoreCoordinator which is the one keeping the cache/snapshots for the objects, or the registered objects in a given NSManagedObjectContext.
In my opinion, there is no reason to "roll your own" cache for CoreData, as this is exactly what you get for free by using the framework.
Your container will have to keep objects keyed by context (an object cannot be shared between contexts) and object ID, so the effect will be the same as calling [context objectRegisteredForID:<objectID>]; or the other methods that access the context current existing objects.
There is a need for a container in a case where you need transient properties to be transferred between contexts and it is costly to recalculate them or obtain their value from scratch.
What is the best way that data loaded from a remote database can be stored locally on iOS. (You don't need to provide any code, I just want want to know the best way conceptually.)
For instance, take Twitter for iOS as an example. When it loads the tweets, does it just pull the tweet data from the remote database and store them in a local database on the iPhone? Or would it be better if the data is just stored locally as an array of objects or something similar?
See, I'm figuring that to be able to use/display the data from the remote database (for instance, in a dynamic table view), the data would have to be stored as objects anyway so maybe they should just be stored as objects in an array. However, when researching this, I did see a lot of articles about local databases, so I was thinking maybe its more efficient to load the remote data as a table and store it in a local database and use data directly from the local table to display the data or something similar.
Which one would require more overhead: storing the data as an array of Tweet objects or as a local database of tweets?
What do you think would be the best way of storing remote data locally (in memory) (for an app that loads data similar to how Twitter for iOS)?
I suppose this begs this prerequisite question: when data from a remote database is downloaded, is it usually loaded as a database table (result set) and therefore stored as one?
Thanks!
While it's very easy the put the fetched data right into your array and use it from there, it is likely that you would be benefitted by using a local database for two main reasons: scalability and persistance.
If you are hoping to download and display a large amount of data, it may be unsafe to try to store it in memory all at once. It would be more scalable to download whatever data you need, store it in a local database, and then fetch only the relevant objects you need to display.
If you download the data and only store it in an array, that data will have to be re-fetched from the remote database and re-parsed on next load of your app/view controller/etc before anything can be displayed. Instead, create a local database in which to store the downloaded data, allowing it to be readily available to display on next load while new data is fetched from your remote source.
While there is some initial overhead incurred in creating your database, the scalability and persistance that provides you is more than enough to warrant that. Storing the state of a remote database in a local database is an extremely common practice.
However, if you do not mind the user having to wait for this data to be fetched on every load, or the amount of data being fetched is relatively low or the data is incredibly simple, you will save time and effort on skipping the local database.
I'm going through the Apress book Pro Core Data and it says the following:
...local caching of remote data can benefit from in-memory persistent
stores.
I fail to see how caching the data in an in-memory persistent store is any more useful than simply having your app's root view controller hang on to the data. Can someone elaborate more fully on the kinds of situations where an in-memory persistent store might be useful?
Your question indicates a misunderstanding of MVC. You've asked "why would it be faster for the model to cache data rather than a controller." Controller don't hold data at all, so it doesn't matter how fast it would or wouldn't be. The model holds data. And in a Core Data app, the model is tied to a persistent store.
The fact that persistent stores can be in memory makes coding extremely convenient, since callers don't have to worry about how the data is stored. In your example, callers would need to behave differently (deal with different classes) for data stored in a local store versus a remote store. Core Data abstracts that away, making it easy to move your store wherever you want it.
The benefit of using Core Data with an in-memory store, as compared to simply rolling out your own non-Core Data class hierarchy, is that you benefit from all the other features of Core Data that are not related to persisting data. These include tracking and undo support, relationship maintenance and change propagation, automatic validation, integration with standard UI components (e.g. NSFetchedResultsController), KVC/KVO, etc.
...local caching of remote data
The key work here is remote data, so you may not want to keep that data around between application launches. In this case an in-Memory store make sense.