There's no reliable way to know when you remove all the children from a view if the children are actually gone from the view hierarchy in iOS. The remove() call in JS executes synchronously, but behind the scenes in iOS, the actual removal of the elements from UI appears to happen asynchronously. Take this sample code:
The output will vary, but often times you will see that the number of children on the win has not been reduced yet, because the child hasn't actually yet been removed from the win on the native side. Here's a sample output, notice the staggering of the decrementing around 23 and 10 due to the asynchronous removal:
It's worth noting that a safer way to remove these children would be in reverse order, as it won't be necessary for the index to change:
This doesn't solve the problem, though, of not knowing when these operations complete. If I was to remove 100 views from win and then add a bunch of new ones to it right after, chances are that some of those views will be added before all of the prior views were actually removed, causing some seriously weird runtime behavior. I've seen this in practice implementing data binding in Alloy. When a Collection of data changes, I need to re-render a section of the UI, removing all its views, and replacing them with the updated data. This is where this problem surfaces constantly for me. I'm sure there are many other use cases.
It is also worth nothing that this problem does not occur on Android. Android appears to process these remove and add calls synchronously making for a simple, safe "remove all" operation.
- Make the remove() and add() calls synchronous. I'm going to assume this isn't going to be possible in concern for performance. That said, it is a parity issue with Android as the remove() API behaves differently on the separate platforms.
- Provide some means of knowing when the remove() call is actually complete, perhaps a callback that can fire when the operation is done.
- A new API, a synchronous setChildren() function that can take an array of child elements. Not only would this allow you to safely remove all elements then add more directly after, but it would also increase overall performance by allowing you to make fewer jumps into native-land when establishing a view hierarchy.
All of these are off the top of my head, or based on a conversation with Blain Hamon. I'm open to anything that allows me to empty a view of all children and know when that operation is complete, preferably in a cross-platform manner.