I'm using a NSMutableDictionary to cache high scores that I pull from Game Center (storing scores by GC rank as key). The pulling happens as soon as the user views that line in a tableview. If there are a million rows and the user views them all, that would mean that the cache fills up to a million rows...
Ok in practice I guess I'll be happy if a million people played my game but still to be on the safe side I'd like to limit the amount of rows that go into the NSMutableDictionary.
Anyone got a simple approach here? Maybe another structure than a dictionary would be useful. My idea was to remove the entries from the dictionary that were the most old, and out of current tableview.
Taken a look at NSCache? ・゜゚・:.。..。.:*・'(゚▽゚)'・:.。. .。.:・゜゚・*
Related
I know how to implement pagination with UITableview but my question is we always append data of next page with existing complete data array so every next page array is increasing array size.
For example - We get 50 records in first page and we request for next page and we again get 50 records and then we will append that records in existing complete array so complete array is now having 100 records. I am requesting data with around 100 pages so my array will have 5000 records as we know holding some starting page array data is not good idea as we hardly come back for starting page after visited 100 pages .
Is there any way to optimize array size? please help me on this as i searched a lot but didn't find good answer for this.
I would be very grateful for help and sorry for my bad english.
I think you can achieve that by writing the "old" data to a local storage, and retrieve and insert back into your array.
So, imagine that you've already fetched, lets say 200 items. So when the user scrolls down, and you fetched the next page (the next 20 items), you "cut" from your array the items from 0 to 99 and write to a file. Now your array has 120 items. Then, when the user continues scrolling and again reached 220 (array.count >= 220), repeat the same logic, and so on.
Now the most interesting part. If the user scrolls back and the index of the top visible cell is <100, you read the previously written data from the file (and remove from the file) and insert into your array at 0 position.
And of course it'd be better to clear all that kind of files on the app launch.
Of course the numbers I wrote below are magic numbers and you should play with them to find the right ones that best fit your needs.
I have some payments(income and expense) which are added to Core Data and every day I calculate the total and also I show how many consecutive days the payments total was positive.
How I am doing right now is always get the total for previous day and increase a counter if its positive. This counter is saved using UserDefaults.
My issue is when lets say the app is deleted and reinstall, the counter is lost, so I am trying to find a way calculate it dynamically every time, but I don't think reading all payments for all days is a good idea in terms of memory.
Another solution is maybe save it using Keychain ?
Is there any other more elegant method? I don't really like the idea of saving this counter.
As an answer
Assuming you reset the counter if the balance goes negative, you just need to load the balance in reverse date order, and count until you go negative?
Depending on how many records you have it may not be performant to read it all in one go. If that's the case read in batches of a manageable size (50 days, perhaps) and only get more data if you are still recording positive balances.
At some point, of course, you may just return "more than 100 days" as a valid response :-)
I am using Firebase to populate a UITableView.
I was wondering if it's possible to have Firebase download the first 5 results, and, once the user has scrolled to the last of these, download the next 5 results.
At the moment, Firebase downloads all of my child nodes at once, but if it did it bit-by-bit, the view would load more quickly.
Any advice?
--EDIT
It's important to note that there are images in the cells. The images are base64 encoded NSStrings. Here is the code I use to retrieve them and turn them into UIImages
NSString* profPicString = [child.value objectForKey: #"profilePicture"];
NSData *dataFromBase64 = [NSData base64DataFromString:profPicString];
UIImage *profPicImage = [[UIImage alloc]initWithData:dataFromBase64];
item.profilePicture = profPicImage;
Initial Thought
I don't know if there is an ideal solution for this, but I would definitely look into complex queries in Firebase's documentation. You can query certain ranges by using the methods queryStartingAtValue and queryEndingAtValue, but you have to make sure your firebase is setup correctly to work with these.
At the bottom of the Range Queries section, it mentions:
Range queries are also useful when you need to paginate your data.
So this might be your ideal solution.
Existing Solution
There is an answer I found that uses what I mentioned above so hopefully it works for you. I will add, I haven't had much luck using these range query methods on my firebase.
Final Thought
Another solution which is probably not the answer you want to hear, but a URL is (hopefully) a lot shorter than a base64 encoded image and could make a large difference in download times when dealing with a lot of data. With this implementation, you only ask for images from a server when you need them and not all at once.
I'm trying load data about 10K records from 6 different tables from my Ultralite DB.
I have created different functions for 6 different tables.
I have tried to load these in parallel using NSInvokeOperations, NSOperations, GCD, Subclassing NSOperation but nothing is working out.
Actually, loading 10K from 1 table takes 4 Sec, and from another 5 Sec, if i keep these 2 in queue it is taking 9 secs. This means my code is not running in parallel.
How to improve performance problem?
There may be multiple ways of doing it.
What i suggest will be :
Set the number of rows for table view to be exact count (10k in your case)
Table view is optimised to create only few number of cells at start(follows pull model). so cellForRowAtIndexPath will be called only for few times at start.
Have an array and fetch only 50 entries at start. Have a counter variable.
When user scrolls table view and count reaches after 50 fetch next 50 items(it will take very less time) and populate cells with next 50 data.
keep on doing same thing.
Hope it works.
You should fetch records in chunks(i.e. fetch 50-60 records at a time in a table). And then when user reach end of the table load another 50 -60 records. Try hands with this library: Bottom Pull to refresh more data in a UITableView
Regarding parallelism go with GCD, and reload respective table when GCD's success block called.
Ok you have to use Para and Time functions look them up online for more info
I have a big table with 70 rows and 10 columns. It's a table of Saturated Water and Steam that shows different values for different cases. For examle, when temperature is 1 the pressure is 0.006571 and volume is 0.001000, when temperature is 2 then pressure is 0.007060 and volume is 0.001000 and so on.But there's not only temperature, pressure and volume columns, there're more. When,for instance, I select temperature from pickerlist and enter 2 into the textbox below the it I need to populate corresponding values of the other physical properties to other textboxes in the view.(in this particular case 0.007060 for p and 0.001000 for v). I'm thinking of implementing Core Data for keeping the data. But on the other hand I think SqLite might be more suitable. Anyway I don't know and would like to get your advice.
It sounds to me like this is static data (physical properties of water don't change much), so you may not even need a database, and as Stephen noted, it is not a lot of data.
For a start, you can just save your data in a plist file in your app resources, read it in at launch (or on opening of the relevant screen) and go from there.
Later, if optimization is needed, you can move to Core Data.
Seventy rows and ten columns is not very much data, even for an iOS device. (My app often has thousands of rows for example.)
I would stick with whatever is easiest to develop, which will probably be Core Data.