変数宣言の型の後に!を付けることでもnilを代入できるようになる。この場合、nilも値も普通に代入できる。(コンパイルエラーにならない)
nilを代入したまま、メソッド呼んだり、プロパティ参照したりすると、そこでプログラムの実行が止まる。

var hoge:String! = "abc"

println(hoge)   // "123"と表示

hoge = nil
println(hoge)   // "nil"と表示

println(hoge.uppercaseString)   // ここで止まる

どっちにしろ、nilかどうかをチェックしないといけないのでこの方法は使わず、変数宣言で?を指定しておいて、値を参照する場合は、if let 〜{}を使うようにするのが、nilチェック忘れをコンパイル時にわかるのでいいんじゃないかな。