OC是C的超集html
在OC中,咱們能夠使用一種名爲內聯複合表達式的語法 http://blog.sunnyxx.com/2014/08/02/objc-weird-code/express
利用這個特性,咱們能夠在iOS開發中寫複雜的頁面佈局時,作到相似HTML的標籤化的語法.使佈局結構和視圖層級清晰明瞭.swift
舉個例子:佈局
有以下佈局需求spa
HTML代碼:.net
<div class="out"> <div class="middle"> <div class="inner"> <p>content1</p> </div> </div> <div class="middle"> <div class="inner"> <p>content2</p> </div> <div class="inner"> <p>content3</p> </div> </div> </div>
能夠看出,HTML代碼的視圖層級關係很是清晰.3d
使用OC代碼佈局,但不使用複合內聯表達式的寫法以下:code
UIView *outContainer = [UIView new]; [self.view addSubview:outContainer]; [outContainer mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; UIView *midContainer1 = [UIView new]; [outContainer addSubview:midContainer1]; [midContainer1 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; UILabel *textLabel1 = [UILabel new]; [midContainer1 addSubview:textLabel1]; [textLabel1 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; UIView *midContainer2 = [UIView new]; [outContainer addSubview:midContainer2]; [midContainer2 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; UILabel *textLabel2 = [UILabel new]; [midContainer2 addSubview:textLabel2]; [textLabel2 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; UILabel *textLabel13 = [UILabel new]; [midContainer2 addSubview:textLabel13]; [textLabel13 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }];
雖然完成了佈局,可是很不容易從代碼看出視圖的層級關係,往後維護的時候就不是很方便了.htm
改用複合內聯表達式後的佈局代碼以下:blog
UIView *outView = ({ UIView *view = [UIView new]; UIView *midView1 = ({ UIView *view = [UIView new]; UILabel *textLabel = ({ UILabel *label = [UILabel new]; //config your label label; }); [view addSubview:textLabel]; [textLabel mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; view; }); [view addSubview:midView1]; [midView1 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; UIView *midView2 = ({ UIView *view = [UIView new]; UILabel *textLabel1 = ({ UILabel *label = [UILabel new]; //config your label label; }); [view addSubview:textLabel1]; [textLabel1 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; UILabel *textLabel2 = ({ UILabel *label = [UILabel new]; //config your label label; }); [view addSubview:textLabel2]; [textLabel2 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; view; }); [view addSubview:midView2]; [midView2 mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }]; view; }); [self.view addSubview:outView]; [outView mas_makeConstraints:^(MASConstraintMaker *make) { //layout code }];
能夠看出層級關係清晰了.而且帶來了額外的2個好處:
1.視圖之間的耦合度下降了.此時能夠複製任意一個內聯表達式中包含的代碼到其餘位置,而不會引發佈局錯誤.
2.不須要絞盡腦汁思考如何命名了,內聯複合表達式中的命名由於做用域的關係沒有衝突了.
而後咱們嘗試在swift中也使用複合內聯表達式
哦噢,報錯了
這說明swift不支持複合內聯表達式.bigView在swift中被編譯器認爲是一個代碼塊.
可是咱們又想使用這種語法帶來的好處,怎麼辦呢?
咱們能夠利用IIFE來模擬. http://weizhifeng.net/immediately-invoked-function-expression.html
({ let view = UIView() contentView.addSubview(view) view.backgroundColor = .green view.snp.makeConstraints({ (m) in m.edges.equalTo(contentView).inset(UIEdgeInsetsMake(3, 3, 3, 3)) }) ({ let label = UILabel() label.backgroundColor = .red label.textColor = .white self.label = label view.addSubview(label) label.snp.makeConstraints({ (m) in m.center.equalTo(view) }) })() })()
關鍵在於尾部的括號!