2016-06-26 84 views
1

這是一個關於swift中用實例變量聲明swift類的最佳實踐的基本問題,所有值將從Firebase回調中接收。什麼是這些選擇當中,最好的辦法還是讓我知道,如果有其他更好的辦法:在Swift中聲明實例變量:可選vs強制展開與初始值

解決方案1:

class User: NSObject { 
    var name:String = "" 

    override init() { 
     super.init() 
    } 
} 

解決方案2:

class User: NSObject { 
    var name:String! 

    override init() { 
     super.init() 
    } 
} 

解決方案3:

class User: NSObject { 
    var name:String? 

    override init() { 
     super.init() 
    } 
} 

解決方案4:

class User: NSObject { 

    var name:String 

    override init() { 
     super.init() 
     // Now I need to init name variable here 
    } 
} 
+3

如果您不需要2階段初始化或與Obj-C交互,請不要使用'!'。如果你不需要'nil'值,不要使用可選項。這基本上都是你需要知道的。 – Sulthan

回答

4

使用隱式解包選項幾乎不是一個好主意。你應該考慮這樣的:如果你確信你將永遠有User你應該初始化對象的namename字符串是這樣的:

class User: NSObject { 
    let name: String 
    init(name: String) { 
     self.name = name 
     super.init() 
    } 
} 

如果你不相信,你會在回調中得到name使用可選的字符串屬性:

class User: NSObject { 
    var name: String? 
} 

這將使您能夠使用if let檢查name有一個值。

如果您使用String!,您的應用程序幾乎肯定會崩潰,因爲您訪問了nil

var name: String = ""也容易讓人誤解,因爲您必須實施檢查字符串是否爲空或包含名稱。

+0

我喜歡第一選擇,但在這種情況下,我需要初始化所有變量,並且我將擁有所有這些long init方法,並且在現實生活中,我將擁有一個字典或另一個對象,以便如何擺脫「屬性」自我警告.name'未在超級初始化。初始化調用' – iOSGeek

+0

你的答案很好,但是你有兩種選擇方式的名稱是錯誤的 - ** **是**顯式**,** ** **是**隱式** 。所以你的帖子的第一行應該是'使用*隱式*解包選項。 。 。 - 請參閱http://andybargh.com/optionals-in-swift/#Implicitly_Unwrapped_Optionals –

+0

謝謝,我的錯字,修復它。 –

1

使用類似

var name:String = "" 

是說,你將被初始化爲「」所有對象

var name:String? 

是說,你知道一個事實,即變量的變量名名稱將在此對象中,並且此名稱屬性可以包含值nil。以這種方式確認它的存在意味着您在使用它之前,需要對其進行初始化。這給你更多的控制權。在大多數情況下只是有類似

String name; 

在其他語言中意思是,如果你使用的名字沒有明確的初始化,那麼你會得到一個空字符串。情況並非如此。用你在說這個屬性名稱對於所有對象都是肯定存在的,但它可能包含也可能不包含數據,但是因爲你使用明確地創建了它?然後你知道一個事實,即它在某個時候它應該包含數據。

var name:String! 

這有點像var name:String =「」在文件的頂部。用你是說當你創建一個對象的時候,你將能夠使用name屬性,因爲它已經被初始化了。這就是爲什麼IBOutlets有而不是。原因是因爲它已經爲你設置。它在使用前已初始化

之間的混淆?來自沒有正確使用它們。如果您對項目有完全的控制權,並且知道什麼時候進入和退出使用,並且您正在控制什麼時候正在創建項目,那麼最好使用。在一個完美控制的自包含環境中,您可以使用,因爲它會像你用來

編程但是,如果你開始添加在視圖控制器是有條件之間的相互作用,而你知道,在某些時候你會需要一個什麼名字財產,但你只是不知道什麼時候?也可以這樣說:

「嘿,我可以只使用和檢查,看看它是否包含!‘’還是不」

,並可以工作,它會好起來的,但佔據空間如果你瀏覽整個應用程序而不實際使用該屬性。當大多數視圖是有條件的時候,你基本上都可以編程所有情況

這就是爲什麼你會去是說你需要這個屬性。你可能不知道什麼時候到了,但它確實有目的。即使該屬性不存在,您仍然可以使用此屬性編寫邏輯,因爲它允許您在不檢查數據的情況下檢查存在。這個事實使得可選項很棒,因爲當你編譯你的應用時,Xcode將能夠梳理它並看到可選標誌。然後它將開始處理可選項。這很重要,因爲什麼

var name:String 

告訴你名字?它已經初始化了嗎?那將會?

,那麼什麼會

print(name) 

意味着編譯器在運行時?那麼,直到你真正運行它纔會知道。這是一個問題,但

print(name!) 

強制可選變數名稱的展開:字符串?。這允許編譯器防止運行時錯誤,因爲有人創建了一個屬性,結果是可選