So, back to what I said before. When you have a cell in a XIB file, you must register the name of the XIB using NSTableView's "register(_:forIdentifier:)" method before is populated with data. This is typically done in some "viewDidLoad" method.
In your particular scenario, the difficulty comes from managing the cell "identifier" property, which controls the reuse of existing cells. In your "tableView(_:viewFor:row:)" method, it doesn't actually matter what your table column identifier is, so long as you use it to choose a cell with a suitable cell identifier. The default is to have them match, because it's easier to keep track of them that way, but it doesn't have to be so.
However, in that delegate method, when you invoke "makeView(withIdentifier:owner:)" specifying a cell identifier that has your XIB file registered against it, the actual cell must have that same identifier. (Otherwise, the documentation says, "makeView(withIdentifier:owner:)" will return nil.) In case you're keeping track, we're now up to 3 flavors of identifier:
1. The column identifier.
2. The cell identifier under which a XIB is registered.
3. The cell identifier in the cell inside the registered XIB.
It's that complicated, I guess, because your XIB file could contain multiple cell prototypes, and be registered mutliple times, so it uses the identifiers of the cells inside the XIB to figure out which one you want.
This is going to be a problem for you if you really have an unlimited number of extra table columns with an unlimited number of extra cell types, because the above mechanism requires the existence of prototype cells with all identifiers that you're going to use. (That can be one XIB file with all the extra cells, or multiple XIB files with one cell each, or anything in between.) If this is true for you, you can't use XIB files, and you will have to create your cells via code (like you showed in your original post), but you should set "view.identifier", not "txt.identifier". Setting view.identifier should let the table view manage and reuse those cells. (If the cells need reconfiguring each time they're reused, you can override "prepareForReuse" in your cell subclass. BTW, setting txt.identifier does nothing useful.)
OK, if you brain hasn't shut down yet, there's more:
— You don't really have to use separate XIB files at all. You can put all your prototypes (assuming the total number of cell types is fixed) in the table itself, using IB. Just make sure they each have a unique identifier. The trick here is to use the table column identifer to choose the cell identifier, rather than to be the cell identifer, in your "tableView(_:viewFor:row:)" method.
— Whether you have prototype cells in the table (in IB) or in separate XIB files, you can use the same cell type (including the same identifier) for as many columns as you want, if the appearance of the cell is appropriate for the column. You don't need different prototypes with different identifiers for each column. Again, you just choose the correct cell identifier for each table column in your "tableView(_:viewFor:row:)" method. This means, BTW, that the same cell instance might be re-used for different columns at different times in your table's lifetime.