We have some code that takes a block table record ID, iterates the entities, and for each one opens, erases and closes it. Thanks to a code profiler we can see that the AcDbObject::close() is *hugely* expensive in such a case (probably due to the clean-up required after erasing an object).
If we instead take the block table record ID, find any AcDbBlockReference objects that refer to that record, and erase *those* instead of iterating and erasing the individual entities, it cuts out 99% of that time delay. It's also a tiny bit neater in the code and easier to understand.
My question is, is this tactic valid? Will it correctly dump (erase) all the nested entities in the block exactly as if I had manually erased them? I can't see why it wouldn't since as far as I know that's the whole point of the AcDbBlockReference object, to manage the entities behind the scenes - but I wanted to check before I made the change permanently.
Thanks in advance.
Solved! Go to Solution.
Erasing block references has no effect on the entities in the BTR. You can erase the BTR instead of the contained entities, but you first have to remove all hard references to it.
Thanks. I realise now that I was forgetting how blocks work... the entities are the *definition* of the block, the reference is simply an instance that uses that definition. We will have to consider a different approach to deal with the speed penalty.
(If you erase all references to the BTR and then erase the BTR, does that clean up the entities? Or do they still need manually cleaning up?)
If you get an iterator from the BTR, you can then walk the entities it contains. Currently we erase each of those. If you erase the BTR itself, does that automatically erase the nested entities? As I understand it the BTR itself has an object ID, and so do each of the nested entities. Erasing just the BTR is no good if it 'leaks' the entities it contained - that's what I'm trying to avoid.
I'm not sure what you mean by "leaks". The BTR is the owner of the entities that it contains, so if you erase the BTR, then the entities that it contains are "effectively" erased and will not be saved when the drawing is saved.
By leak I mean in the C++ memory sense... an entity being left behind in the database with nothing referring to it or owning it. I realise that technically it isn't leaked since the database owns it, but from our code's point of view it is no longer in the chain of objects and thus has become orphaned.
You did answer my question, though - erasing the BTR is enough - so thanks.