So I have a UITableView in which I am doing batch insert/delete/reloads into. Every once in a while, the list data changes, so I batch update the differences in the list. I'm basically inserting new rows, deleting rows that are no longer there, and reloading rows that exist in both the old and new data. For example:
Before, the list data looks like this:
0: apple
1: banana
2: carrot
After, the list data looks like this:
0: banana
1: carrot
2: dog
3: elephant
This results in deleting row 0, reloading rows 1 and 2, and inserting at rows 2 and 3. The order I call the methods is also in this way: delete, then reload, then insert rows.
However, this results in a exception being thrown since I'm doing two different animations on row 2 (reloading and inserting). Is this an ordering issue, or are my indexPaths incorrect? Note: I need to reload old cells, since the data for that row may have changed, but should not be represented by an insertion/deletion.
Edit: Weirdly enough, this error only happens in iOS versions earlier than iOS4.
I'd say delete 0, and insert 3 and 4. Reloading shouldn't be needed. The order in which you send the updates is irrelevant. Make sure that your model reflects the changes before you tell about the updates. Wrap the calls up with -beginUpdates: end -endUpdates:.
Here is a link for batch update, see listing 7-8:
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html#//apple_ref/doc/uid/TP40007451-CH10-SW16
The WWDC video hint is good, too. You want to look out for Session 128 - Mastering Table Views.
Related
I am trying out the new clickhouse lightweight deletes, which deletes rows on the next merge but asynchronously 'marks' them immediately so that they are not shown in subsequent queries.
The guide i am following is here: https://clickhouse.com/docs/en/sql-reference/statements/delete/
But this doesn't seem to be happening as expected. After deletion it takes about 2-3 minutes before my returned queries are excluded from the results. am I missing something here?
E.g.
I have a collapsingMergeTree table called 'tests' with the following three rows:
Id
name
syGGJVGETbzKMkayoYYaAg
kieren
wFhZdsdjf1xmcHGqK1CQQf
mike
abfZrhYkiafg7qr9jAwseG
peter
I attempt to run
DELETE FROM test WHERE Id = 'syGGJVGETbzKMkayoYYaAg' SETTINGS allow_experimental_lightweight_delete=1;
// OR
SET allow_experimental_lightweight_delete=1;
DELETE FROM test WHERE Id = 'syGGJVGETbzKMkayoYYaAg'
However when I run the query I still get the deleted record in results, until about 5 minutes later.
I am using the clickhouse docker image (clickhouse/clickhouse-server) for my tests locally.
Thanks in advance for your help.
--- what did you try ---
Tried the documents code and expected that the results would be hidden immediately and deleted on the background as the page indicates so.
Please let me know if I am doing anything wrong or missing something
DELETE FROM test is async by default. Not only process of deletion but DELETE itself as well.
you can use mutations_sync=2:
DELETE FROM test
WHERE Id = 'syGGJVGETbzKMkayoYYaAg'
SETTINGS allow_experimental_lightweight_delete=1, mutations_sync=2;
It makes your delete synchronous.
( this behaviour was changed today BTW https://github.com/ClickHouse/ClickHouse/pull/44718 )
So currently you run DELETE FROM test ... it returns control immediately and does nothing!!! except it creates a mutation. This mutation asynchronously in the background changes the invisible column _deleted for rows matching WHERE condition, this process can take seconds, minutes, hours, days. After that your selects will not see these rows. After that eventually OR NEVER the marked rows will be deleted during merges, this can take months.
When I manually (or via office.js code) insert rows into a table that is in a content control, it increases the number of content controls in the contentControls collection. Word 2016 Windows version 1611.
For example, if I have 1 table in 1 content control, initially the contentControls.items.length = 1. If I insert 3 rows, then the contentControls.items.length = 4.
Word.run(function (context) {
var contentCntrls = context.document.contentControls;
context.load(contentCntrls, "tag");
return context.sync().then(function () {
app.showNotification("contentCntrls.items.length: " + contentCntrls.items.length, "");
});
})
This produces errors ("Internal Error") in subsequent code that uses the contentControls collection and eventually freezes/crashes Word.
This behavior happens with both the beta and version 1 office.js code.
The issue occurs on Windows, but works fine on Macs.
The count of content controls does not change if I check it via VBA: Debug.Print ActiveDocument.ContentControls.Count
If the user saves changes (after inserting rows), then the issue does not occur.
Is this a bug or am I doing something wrong? Is there some workaround (perhaps to reset the CC collection)?
UPDATE: The issue is fixed. (REF: 1461591)
Update: we found a bug on this. Happens when the document is stored in OneDrive. we are in the process of fixing it.
--------------LEAVING ORIGINAL ANSWER FOR REFERENCE ---------------------
I was trying to repro this issue, but i am not able to. I tried 2 different paths to test the scenario:
inserted a table, selected the whole table and manually inserted a content control.
inserted a content control, added a few paragraphs then a table inside.
After adding rows to the 1 and 2 tables I did not see the item.length increasing as you describe, it stayed at 1 content control.
Also there is no such thing as build 1611 for Windows. Can you please provide more details on:
how are you inserting the table and the content control
Verify the build number. I tried it in the latest publicly available build which is 16.7766.2068, make sure to update your client before testing.
thanks!
I have about 2000 rows in a SQLite database. Each row has an integer ID and a string value. I'd like to populate them into a UITableView with an alphabetical index like the Contacts app does.
Is it feasible to achieve performance that's as good as the Contacts app without using CoreData, providing I don't need to re-implement everything that CoreData does for you (e.g. caching etc)?
I have tried to implement this using paging with 50 rows per page, and pre-load the next page in another thread when the tableview has scrolled past 25 rows. This works if the scrolling isn't very quick, but still lags when it's scrolled really quickly. I think the step to populate a temporary NSArray of 50 items is taking a long time.
Furthermore, this approach does not work very well for the index for the UITableView because the loading is done sequentially whereas the index skips. I thought about loading the first 10 rows for each index key at initialisation but again, it will be quite slow (populating an array with 260 items).
Any suggestions?
It looks like performance for fetching a few thousand rows at once should not be a big deal (You should just be able to pre-fetch them).
I would asynchronously run a SELECT on your table for whatever columns you want (like the index for reference and maybe just the string to be displayed) and throw them into an NSMutableDictionary keyed on the index and then reload the table data. The cellForRowAtIndexPath UITableViewDataSource function would use this dictionary.
If you allow users selecting a row to see details, you can then run a query for the rest of the data for that row upon selection.
Doing the initial fetch asynchronously in ViewDidLoad or ViewWillAppear will prevent the UI from locking up when the user goes to view the table and in almost all cases the table should already be visible once they actually see the table.
initial fetch(performed on a background thread, followed by the table reloading on the main thread)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^()
{
//perform your query here
dispatch_async(dispatch_get_main_queue(), ^()
{
[self.tableView reloadData]
});
});
i am taking example of A-Z only
take 26 section in table.
there will be 26 query for fetching data
first for starting with A
second is for starting with B
third is for starting with C...... and on upto Z
in cellForRowAtIndexPath().
till the user dont scroll the table it wont fetch data for other alpha bets.
if each From A to Z contain 100 name(text).
still it wont take too much time.
hope you can get idea from here..
If i want to insert few rows in the middle of the existing table, how do i approach it? Where all that i should be careful when doing such thing? Is there any good sample source available?
Appreciate your helps.
Thank you.
Tableviews don't contain data and they don't actually contain rows themselves. Instead, tableviews are just an illusion created by redisplaying the same tableviewcell objects over and over again with different data each time. The real table, the real rows, are actually in the logical data.
So, to " insert few rows in the middle of the existing table" you actually add the rows into the data that the table displays. For example, if you had a simple array of names that you display in the table, you would insert the new names into the array. Then you would call -[UITableView reload] which will cause the table to ask the datasource for the new data.
See the Table View Programing Guide for iPhone OS.
Insert the data into your model and call reloadData on the table. If you need to animate the insertion for some reason, you can use insertRowsAtIndexPaths:withRowAnimation:, but the principle if updating the model first still applies.
I've enabled editing mode and moving cells around to allow users to position table view content in the order they please. I'm using Core Data as the data source, which sorts the content by the attribute "userOrder". When content is first inserted, userOrder is set to a random value. The idea is that when the user moves a cell around, the userOrder of that cell changes to accomodate its new position. The following are problems I am running into while trying to accomplish this:
Successfully saving the the new location of the cell and adjusting all changed locations of influenced cells.
Getting the data to be consistent. For example, the TableView handles the movement fine, but when i click on the new location of the cell, it displays data for the old cell that used to be that location. Data of all influenced cells gets messed up as well.
I know I have to implement this in:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {}
I just don't know how. The apple docs are not particularly helpful if you are using Core Data, as in my situation.
Any guidance greatly appreciated!
Problem 1 is pretty much independent of using CoreData, just think of a simple array:
{0 1 2 3 4 A}.
Now the user moves some freshly appended element A within the Array:
{0 1 A 2 3 4}
So starting with the inserted element A, which receives the index 2, all elements need to have their index (which is userOrder in your case) incremented by one.
So you map 0->0, 1->1, A->2, 2->3, 3->4 and so on.
Problem 2 may have two or three sources:
Either your CoreData values are not synced so the database is not in sync with what you see.
[table reloadData] was not called
Your move-Algorithm is wrong
So perhaps you can check the thee points above and if none applies you could consider posting your move-algorithm for closer examination.