Swift 的語言特性使得它非常適合被用于以函數式編程思想,如果你還沒開始用函數式的方式來使用它,那么可以從現在開始刑赶,嘗試著利用函數式的便利性。
let indicateView = UIImageView(frame: view.frame)
indicateView.image = UIImage(named: "how2use")
self.view.addSubview(indicateView)
我剛剛寫了上面這段代碼懂衩,來讓我的當前頁面顯示名為 “how2use” 的這張圖片撞叨。看起來好像是我做了三件事:
- 根據 frame 創(chuàng)建 UIImageView
- 根據圖片名稱配置 UIImageView
- 將 UIImageView 作為 subview 傳給其他 view
但是實際上浊洞,我只需要 frame牵敷、imageName 這兩個東西就可以把這三行代碼配置好,或者說我能不能用這兩個參數來把上面的三行代碼縮減為一行法希。
extension UIImageView {
func frameSelf (rect:CGRect) -> UIImageView {
self.frame = rect
return self
}
func imageSelf (imageName:String) -> UIImageView {
self.image = UIImage(named: imageName)
return self
}
func placeSelf (view:UIView) -> UIImageView {
view.addSubview(self)
return self
}
}
寫了上面這些方法之后劣领,代碼修改成這個樣子了:
let indicateView = UIImageView()
.frameSelf(view.frame)
.imageSelf("how2use")
.placeSelf(self.view)
為了代碼可讀性,這里我寫了四行铁材,但顯然這是一行代碼。
繼而我發(fā)現 indicateView 這個名字沒有存在的必要奕锌,于是我廢棄掉 placeSelf 這個方法著觉,改成這樣:
self.view.addSubview(UIImageView()
.frameSelf(view.frame)
.imageSelf("how2use"))
一行代碼,不引入多余的變量惊暴。
如果你愿意的話饼丘,這個模式還可以繼續(xù)寫下去。
extension UIImageView {
func tagSelf (tag:Int) -> UIImageView {
self.tag = tag
return self
}
func modeSelf(contentMode:UIViewContentMode) -> UIImageView {
self.contentMode = contentMode
return self
}
}
最后代碼會變成這種形式:
NSObject().func1().func2().func3()......
思考
- 上面這些代碼的優(yōu)勢在于:類似 indicateView 這種東西辽话,用一次就不要了肄鸽,沒必要引入新的名稱,不便于理解和記憶油啤,我們就可以函數式地把它解決掉典徘,代碼更精簡易讀。
- 上面我用了 xxxxSelf 這種方式來表明益咬,這種方法不是用一下就完了逮诲,它會返回這個對象本身,所以你還可以繼續(xù)做別的事情幽告。但是這種命名方式我個人看來不夠好梅鹦,唯一好的地方可能只是在于:本來我想設置 imageView.tag = 100,結果敲出 tag 這三個字母冗锁,Xcode 就提示我有 tagSelf 這個方法可以用齐唆,這可以讓我方便地自動補全這個方法,不需要記憶方法名冻河。
- 這種編程方式的優(yōu)點之一在于不同方法之間的組合性箍邮,如果你想把上面這些方法整合到一個函數里茉帅,然后通過傳一大堆的參數來進行調用,是畫蛇添足媒殉。
- 顯然這種方式有其弊端担敌,不宜濫用,而且修改代碼的時候要注意:假如你要改動 func2廷蓉,注意它和 func1全封、func3 之間是不是存在什么先后關系。特別是你用這種方式來給圖片做濾鏡處理的時候桃犬,一張圖片先高斯模糊再打馬賽克刹悴,先打馬賽克再高斯模糊是完全不同的。
userImage.blur().mosaic() // 馬賽克本身是清晰的
userImage.mosaic().blur() // 馬賽克本身是模糊的
推薦一下個人博客:kyxu.tech