Swift-通過協(xié)議的方式為某個類擴展一個屬性

本例中节仿,1晤锥、我們展示的是為UIView擴展一個sd屬性。sd屬性是SDAutoLayout類型廊宪。2矾瘾、為UIView添加一個靜態(tài)sd屬性,可示自定義靜態(tài)方法或屬性


1箭启、聲明協(xié)議壕翩,并為協(xié)議提供默認實現(xiàn),添加sd屬性傅寡。

/** --------------------------------------------
 * 為UIView擴展一個sd添加屬性放妈,然后再提供一個默認layout()函數(shù),返回的是SDAutoLayoutModel類
 * 方便鏈式調(diào)用
 * 防止UIView中有l(wèi)ayout方法赏僧,然后重名
 * -----------------------------------------------
 */

public protocol SDAutoLayoutCompatible {
    /// associatedtype關鍵字用來指定關聯(lián)類型
    associatedtype T
    /// 添加一個為只讀的關聯(lián)屬性:sd
    var sd: T { get }
}

/// 協(xié)議擴展大猛,可提供默認實現(xiàn),返回一個SDAutoLayout類型對象。
extension SDAutoLayoutCompatible {
    // sd:關聯(lián)SDAutoLayout類型的屬性 默認實現(xiàn)
    public var sd: SDAutoLayout<Self> {
        get {
            return SDAutoLayout.init(self)
        }
    }
}

擴展屬性的類型淀零,一般為一個class類挽绩。
上面協(xié)議所擴展一個sd屬性,其類型為SDAutoLayout

/// 聲明一個類驾中,為此類擴展并指定類型
public final class SDAutoLayout<Base> {
    public let base: Base
    public init(_ base: Base) {
        self.base = base
    }
}

/// 擴展SDAutoLayout唉堪,并指定類型為UIView, 為其添加一個layout()方法
// 為UIView擴展的sd添加方法
extension SDAutoLayout where Base: UIView {
    /// 可通過UIView().sd.layout().leftSpace來調(diào)用。防止layout方法重名
    @discardableResult // 未使用的返回值警告消除
    func layout() -> SDAutoLayoutModel {
        return base.sd_layout()
    }
}

UIView擴展實現(xiàn)SDAutoLayoutCompatible肩民,那么它就擁有了sd屬性

/// 為UIView添加一個擴展唠亚,并實現(xiàn)協(xié)議,讓它有sd關聯(lián)屬性持痰,默認為SDAutoLayout類型
extension UIView: SDAutoLayoutCompatible {}

2灶搜、為類或結構體添加靜態(tài)屬性、成員屬性

/** --------------------------------------------
 * 為UIView擴展一個sd屬性,一個sd靜態(tài)屬性割卖,
 * 方便鏈式調(diào)用
 * 防止UIView中有l(wèi)ayout方法前酿,然后重名
 * -----------------------------------------------
 */
public protocol SDAutoLayoutCompatible {}

/// 協(xié)議擴展,可提供默認實現(xiàn),返回一個SDAutoLayout類型對象鹏溯。
extension SDAutoLayoutCompatible {
    // sd:關聯(lián)SDAutoLayout類型的屬性 默認實現(xiàn)
    public var sd: SDAutoLayout<Self> {
        get {
            return SDAutoLayout.init(self)
        }
    }
    // 靜態(tài)屬性
    public static var sd: SDAutoLayout<Self>.Type {
        get {
            return SDAutoLayout<Self>.self
        }
    }
}

/// 聲明一個結構體罢维,為此類擴展并指定類型
public struct SDAutoLayout<Base> {
    public let base: Base
    public init(_ base: Base) {
        self.base = base
    }
}

/// 擴展SDAutoLayout,并指定類型為UIView, 為其添加一個layout屬性, 靜態(tài)方法或靜態(tài)屬性
// 要擴展sd屬性的方法或屬性都在這里實現(xiàn)即可
extension SDAutoLayout where Base: UIView {
 
    /// 可通過UIView().sd.layout.leftSpace來調(diào)用丙挽。防止layout方法重名
    var layout: SDAutoLayoutModel {
        get {
            return base.sd_layout()
        }
    }
    
    /// 靜態(tài)方法
    @discardableResult // 未使用的返回值警告消除
    public static func getView() -> UIView {
        DXLog(message: "通過sd靜態(tài)屬性調(diào)用方法UIView.init: \(Base.init())")
        return Base.init()
    }
    
    /// 默認背景顏色
    static var defaultBgColor: UIColor {
        get {
            return UIColor.green
        }
    }
}

/// 為UIView添加一個擴展肺孵,并實現(xiàn)協(xié)議,讓它有sd關聯(lián)屬性颜阐,默認為SDAutoLayout類型
extension UIView: SDAutoLayoutCompatible {}

3平窘、使用

靜態(tài)屬性的使用
let view = UIView.sd.getView()
self.view.backgroundColor = UIView.sd.defaultBgColor

實例屬性的使用
imageView!.sd.layout().leftTo(contentView, 10)
            .topTo(contentView, 10)
            .width(is: 70).height(is: 100)
textLabel!.sd.layout().centerYEqualTo(contentView)
            .leftTo(imageView!, 10)
            .rightTo(contentView, 10)
            .autoHeight(0)// 高度自適配

4、 swift中Self 瞬浓、.self 初婆、.Type是什么

  • Self關鍵字
    • swfit5.1開始蓬坡, 可用Self替代類名來訪問靜態(tài)成員
    class ListViewController: UITableViewController {
      static let cellReuseIdentifier = "list-cell-identifier"
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        tableView.register(
            ListTableViewCell.self,
            forCellReuseIdentifier: Self.cellReuseIdentifier
        )
      }
    }
    
    • Self在未知具體類型的上下文中動態(tài)引用實際上的類型猿棉,例如,通過在協(xié)議擴展中引用協(xié)議的具體實現(xiàn)類型
    extension Numeric {
      func incremented(by value: Self = 1) -> Self {
          return self + value
      }
    }
    給Numeric協(xié)議擴展了一個自增的方法屑咳,
    但是我們現(xiàn)在不知道具體自增的類型萨赁,使用Self作為返回類型,則可以動態(tài)獲取對應的類型:
    let num1 = 5.incremented()           //num1: Int
    let num2 = 5.0.incremented()         //num2: Double
    
  • .Type關鍵字
    Swift 中的元類型用 .Type 表示兆龙。比如 Int.Type 就是 Int 的元類型杖爽。
    類型與值有著不同的形式,就像 Int 與 5 的關系紫皇。元類型也是類似慰安,.Type 是類型,類型的 .self 是元類型的值聪铺。
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末化焕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子铃剔,更是在濱河造成了極大的恐慌撒桨,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件键兜,死亡現(xiàn)場離奇詭異凤类,居然都是意外死亡,警方通過查閱死者的電腦和手機普气,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門谜疤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事夷磕∥郑” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵企锌,是天一觀的道長榆浓。 經(jīng)常有香客問我,道長撕攒,這世上最難降的妖魔是什么陡鹃? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮抖坪,結果婚禮上萍鲸,老公的妹妹穿的比我還像新娘。我一直安慰自己擦俐,他們只是感情好脊阴,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蚯瞧,像睡著了一般嘿期。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上埋合,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天备徐,我揣著相機與錄音,去河邊找鬼甚颂。 笑死蜜猾,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的振诬。 我是一名探鬼主播蹭睡,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赶么!你這毒婦竟也來了肩豁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤禽绪,失蹤者是張志新(化名)和其女友劉穎蓖救,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體印屁,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡循捺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了雄人。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片从橘。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡念赶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出恰力,到底是詐尸還是另有隱情叉谜,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布踩萎,位于F島的核電站停局,受9級特大地震影響,放射性物質發(fā)生泄漏香府。R本人自食惡果不足惜董栽,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望企孩。 院中可真熱鬧锭碳,春花似錦、人聲如沸勿璃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽补疑。三九已至歧沪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間癣丧,已是汗流浹背槽畔。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胁编,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓鳞尔,卻偏偏與公主長得像嬉橙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子寥假,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容