The best, IMHO, is to keep your objects in a separate TStringList and keep it synchronized with Tabs, which basically means responding to adding/deleting a tab and a tab changing its position (e.g. when the user drags a tab to put it before/after another), if this last is allowed in your program.
So, yeah, what you outlined seems to be the best solution. Only, remember that TStrings is a quasi-abstract class and that its default implementation is TStringList, so use one of these.