The Inactive/Activate mechanism is much more versatile than HoldForm. It allows controlled evaluation of parts or all of an expression. This is certainly useful in didactic expositions (The automatic evaluation of so many expressions has always been a problem and this plugs the hole.) and it might also be useful in investigating which parts of an expression are causing a problem.
There are many examples in the Inactive help page.
Here is an example of nested Inactive expressions being evaluated. (Unfortunately I don't know how to suppress the Inactive display in the output.) We can evaluate with one command, or evaluate the inner Inactive first. Ah, but what if the inner Inactive was also a Cos? Then you have to use Map or MapAt, which you could also have done with HoldForm.
In:= expr = Inactive[Cos][Inactive[ArcSin][1/2]]
Activate[expr, ArcSin | Cos]
With HoldForm all you can do is use ReleaseHold twice.
expr2 = HoldForm[Cos[HoldForm[ArcSin[1/2]]]];
% // ReleaseHold // ReleaseHold