Names are unreliable. 3 months down the line you may change a name of some widget without realizing it, and a month later realize that "oh shit, something isn't working" -- and then good luck trying to find what widget you changed and what it was. References, on the other hand... if you change the name or drag a widget elsewhere, they will still work properly.
In Windward, I have a "GamePrefabs" class that's accessible via a singleton reference, placed on a game object saved as a prefab, and I have it present in every scene. This prefab contains references to commonly used prefabs -- cannonball, effect sounds, explosions, etc. So when my scripts want something, such as create an explosion at point A, I simply create a new instance of GamePrefabs.instance.explosion.
If I ever decide to change the explosion, it's as simple as replacing the reference on that one prefab, and all scenes will be automatically affected. I don't have to dig through code and replace some obscure string names.
Another example -- I have a main menu in Windward. This menu has a central script attached to the root of its prefab that references all common components -- sub-windows it can open up, important input fields it needs to know about -- everything that the script needs in order to work, and nothing more. This script is the only place where these references are used.
With proper class design and hierarchy, there is absolutely no need to have something absurd like "class1.hud.widgets.panel3.widgetpack1.thereiam". Furthermore, look into NGUITools.Broadcast (or UIRoot.Broadcast for that matter) -- you can use it to trigger abstract events discretely -- which is a slow operation, but if you don't use it in every Update, perfectly acceptable. It's perfect for when you want to signal an event to some script you don't know the location of (or don't care where it's located), making your code clean, abstract, and without any trace of ugly spaghetti code.