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)想到了,編譯器會(huì)報(bào)錯(cuò),因?yàn)槲覀冊(cè)趪L試修改一個(gè)常量數(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.”

那么,另外一個(gè)問題來了:同樣是用下標(biāo)訪問,同樣是值類型(Value Type),為什么UnsafeMutablePointer不會(huì)報(bào)錯(cuò)?
UnsafeMutablePointer和Array都是struct,存儲(chǔ)的類型也一樣都是Int,額……
Array:
public subscript (index: Int) -> Element
UnsafeMutablePointer:
public subscript (i: Int) -> Memory { get nonmutating set }
nonmutating是什么東西?!
nonmutating
nonmutating是swift的一個(gè)關(guān)鍵字,它和mutating一樣用來修飾方法,只不過nonmutating一般用來修飾setter方法。
當(dāng)用nonmutating修飾setter方法的時(shí)候,swift編譯器會(huì)知道該方法并不會(huì)改變常量變量,因此不會(huì)報(bào)錯(cuò)。
使用nonmutating有一定的危險(xiǎn)性,因?yàn)樗^了swift編譯器的安全檢查機(jī)制。不過我們可以在合適的情況下使用它,寫出更加靈活的代碼
假設(shè)我們想通過下標(biāo)訪問NSUserDefaults,我們會(huì)這么做:
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是不是有點(diǎn)class的感覺?