Swift tricks系列收集Swift牛逼的patterns和讓你代碼更加Swifty的tricks派近,持續(xù)更新中……
開始今天的話題前算芯,我們先來看幾行代碼:
let unsafemutablepointer : UnsafeMutablePointer<Int>
unsafemutablepointer = UnsafeMutablePointer.alloc(3)
unsafemutablepointer[0] = 1
unsafemutablepointer[1] = 2
unsafemutablepointer[2] = 3
///////////
let intArray : Array<Int> = [1,2,3]
intArray[1] = 3
****上面代碼有什么問題抖剿?****
可能你已經(jīng)想到了灼捂,編譯器會報錯渤涌,因為我們在嘗試修改一個常量數(shù)組片吊。
“If you create an instance of a structure and assign that instance to a constant, you cannot modify the instance’s properties, even if they were declared as variable properties”
“This behavior is due to structures being value types. When an instance of a value type is marked as a constant, so are all of its properties.”
那么绽昏,另外一個問題來了:同樣是用下標(biāo)訪問,同樣是值類型(Value Type)俏脊,為什么UnsafeMutablePointer
不會報錯全谤?
UnsafeMutablePointer
和Array
都是struct
,存儲的類型也一樣都是Int
联予,額……
Array:
public subscript (index: Int) -> Element
UnsafeMutablePointer:
public subscript (i: Int) -> Memory { get nonmutating set }
nonmutating
是什么東西啼县?材原!
nonmutating
nonmutating
是swift的一個關(guān)鍵字,它和mutating
一樣用來修飾方法季眷,只不過nonmutating
一般用來修飾setter方法余蟹。
當(dāng)用nonmutating
修飾setter方法的時候,swift編譯器會知道該方法并不會改變常量變量子刮,因此不會報錯威酒。
使用nonmutating有一定的危險性,因為它跳過了swift編譯器的安全檢查機(jī)制挺峡。不過我們可以在合適的情況下使用它葵孤,寫出更加靈活的代碼
假設(shè)我們想通過下標(biāo)訪問NSUserDefaults
,我們會這么做:
extension NSUserDefaults {
subscript(key: String) -> AnyObject? {
get { return objectForKey(key) }
set { setObject(newValue, forKey: key) }
}
}
var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults["key"] = "value"
不幸的是橱赠,defaults
是mutable的尤仍,這就意味著它可以被別人重新賦值,進(jìn)而引發(fā)問題狭姨。使用nonmutating
宰啦,我們就可以這樣做:
protocol NSUserDefaultsSubscipt {
subscript(key: String) -> AnyObject? { get nonmutating set }
}
extension NSUserDefaults:NSUserDefaultsSubscipt {
subscript(key: String) -> AnyObject? {
get { return objectForKey(key) }
set { setObject(newValue, forKey: key) }
}
}
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults["key"] = "value"
現(xiàn)在再看defaults
是不是有點class的感覺?