[譯]iOS用戶界面:Storyboards vs. NIBs vs. Custom Code

原文見這里

我常聽見iOS程序員問類似這樣的問題:

iOS開發(fā)界面的最好的方法是:Storyboard,NIBs,還是代碼?

對這個問題的各種答案嘹黔,似乎明示或暗示著,必有一個唯一的選擇莫瞬,這個選擇往往要在開發(fā)之前就要做出儡蔓。

我的看法,這個問題的答案應(yīng)該是以一個或多個類似問題的形式來給出疼邀。

哪款車是“最好的”喂江?

來舉一個題外的例子。假如我想買一輛車檩小,我問你一個“簡單”問題:“我的最佳選擇是什么开呐?”

你能真的給我建議一個車型,甚至是一個品牌來回答我的問題嗎?恐怕不能筐付。除非你建議“法拉利”卵惦。相反,你更可能會通過問一些問題來回答:

  • 你有多少錢瓦戚?
  • 你需要幾個座兒沮尿?
  • 你對油耗有多在意?
  • 你覺得越野車怎么樣较解?

很顯然畜疾,除非在特定前提下,否則沒有“好車”或“壞車”之分——只有在需求確定的前提下才有好車印衔、壞車之分啡捶。

回到iOS UI設(shè)計問題

就像剛才選車的問題一樣,“開發(fā)iOS UI的最好的方法是什么”這個問題也缺少特定前提奸焙。令你意外的是瞎暑,這個問題的答案也不需要解決所有問題。

概括地說与帆,有三種開發(fā)UI的方法可供你選擇熬丧,并且每一種都各有長短诡宗,各有粉絲和吐槽者静浴。

  • iOS Storyboards: 一個可視化的工具即横,可以放置多個views以及他們之間的過渡
  • NIBs(or XIBs): 每個NIB文件對應(yīng)于一個單獨的view元素,可以放置在Interface Builder中阵翎,故也算一個可視化工具逢并。注:“NIB”這個名字來源于文件后綴(以前是.nib,現(xiàn)在是.xib贮喧,盡管現(xiàn)在還是讀“NIB”)
  • 純代碼: 沒有GUI工具筒狠,用程序的方式來處理所有的位置設(shè)置、動畫等效果

這些選擇中箱沦,任何一個都不比另外的一個“更好”(盡管你可能聽說過哪個更好)。

例如:Storyboards雇庙,是最遲加入到iOS UI工具包中的谓形。我曾聽說“他們將是未來,將替代NIBs和代碼UI”疆前。但是寒跳,我只把Storyboards看作一個利器,而不是一個完全替代NIBs和代碼的替代者竹椒。Storyboards在某些場合是正確的選擇童太,但也不是所有場合。

toptal-blog-image-1396377741412.png

進一步說,如果你(在一個工程中)可以使用任意一個书释,最恰當?shù)亟鉀Q某個特定問題翘贮,那為什么要保守一個選擇不放呢?

在我的觀點中爆惧,這個問題可以提升到一個更高層次狸页,其答案在我的一系列“軟件開發(fā)原理”中排名還很靠前,這個答案就是:沒有哪一種萬能的語言扯再,萬能的框架或技術(shù)對軟件開發(fā)中的任意問題都是絕對最好的解決方案芍耘。 iOS UI設(shè)計問題也是如此。

本篇iOS開發(fā)引導(dǎo)中熄阻,我們將逐一介紹以上每一種方法斋竞,以及哪些場合適用,哪些場合不適用秃殉,已經(jīng)哪些場合兼而用之窃页。

iOS Storyboards

新手常犯的一個典型錯誤是:創(chuàng)建一個工程級巨大的Storyboard,當然复濒,我剛開始用時也犯了這個錯誤脖卖。

新手常犯的一個典型錯誤是:創(chuàng)建一個工程級巨大的Storyboard。一個Storyboard上是呈現(xiàn)了一個“故事”巧颈,而不應(yīng)該將不相關(guān)的很多故事混合在一起

顧名思義畦木,一個Storyboard就是一個“有故事要講”的板,不應(yīng)該將不相關(guān)的很多故事混合在一起砸泛。一個Storyboard應(yīng)該包含一系列在邏輯上有關(guān)聯(lián)的view controller十籍,而不是所有。

舉例來說唇礁,處理下列問題是使用Storyboard是合理的:

  • 授權(quán)和注冊所需的一系列views
  • 由多步組成的訂閱入口
  • 類似于引導(dǎo)的事務(wù)流
  • 此處不會譯

同時勾栗,應(yīng)避免太大的Storyboard,也要避免整個App就一個Storyboard(除非App相對比較簡單)盏筐。在我們深入探討之前围俘,先來看看為什么。

超大Storyboard的不便之處

超大的Storyboard琢融,不但很難瀏覽界牡、很難維護,還給團隊引入了一層復(fù)雜性:當多個程序員同時在一個Storyboard工作時漾抬,代碼沖突就在所難免宿亡。因為Storyboard本質(zhì)上是文本文件(xml),merge往往不是一件很容易的事纳令。

程序員看代碼時挽荠,是通過代碼的語義來理解克胳。所以手工合并時,可以讀懂沖突的兩邊文件圈匆,并相應(yīng)處理漠另。而Storyboard是由xcode管理的xml,每行代碼的往往并不好弄明白臭脓。

舉一個很簡單的栗子:假如兩個程序員都改變了一個UILabel(使用了自動布局)的位置酗钞,后提交(試圖提交)的取到已提交者的代碼,就會產(chǎn)生下面的沖突(注意已沖突的id屬性):

<layoutGuides>
    <viewControllerLayoutGuide type="top" id="ar5-ed-tdC"/>
    <viewControllerLayoutGuide type="bottom" id="enX-PS-xZQ"/>
</layoutGuides>

<layoutGuides>
    <viewControllerLayoutGuide type="top" id="6cK-2r-Dvq"/>
    <viewControllerLayoutGuide type="bottom" id="EbB-ky-ghh"/>
</layoutGuides>

id屬性本身沒有提供任何有用的信息来累,所以你不知道該怎么做砚作。唯一合理的做法是從兩邊選一個、舍棄另一個嘹锁。但這樣會不會有神馬“副作用”呢葫录?誰知道?反正你不知道领猾。

?為了使UI設(shè)計問題簡化米同,建議在一個工程中使用多個Storyboard。

何時使用Storyboard

Storyboard最好被用于彼此有聯(lián)系的多個view controller時摔竿,這樣主要是能簡化view controller直接的切換面粮。一定程度上,他們可以被看做NIBs的可視化和view controller之間切換的組合继低。

除了簡化切換熬苍,另一個顯著的好處是可以省去一些代碼,諸如:pop袁翁,push柴底,present 以及 dismiss view controllers。另外view controller是自動分配粱胜,所以無需alloc init

最后柄驻,雖然說最好是應(yīng)用于“多個”view controllers的場景,但對“單個”table view controller應(yīng)用Storyboard也是蠻好的焙压。原因有3:

  • 可以當場設(shè)計tabel cell原型鸿脓,所有的東西都在一起
  • 多個cell模板可以在父table view controller中設(shè)計
  • 使創(chuàng)建static table views成為可能

有人會說,多個cell模板也可以用NIBs來設(shè)計冗恨。當然答憔,這只是個人喜好問題:有的人喜好所有東西都放在一起,有的人卻無所謂掀抹。

何時不要 用Storyboard

下面這些情況:

  • 如果view有很復(fù)雜的Layout,或動態(tài)Layout心俗,最好用代碼實現(xiàn)
  • 如果view已經(jīng)用NIB或代碼實現(xiàn)

【譯者:下面這段我不是太理解傲武,就大概翻譯一下】
這些情況蓉驹,要么把view從storyboard提出去,要么把他嵌入到view controller中揪利。前一種做法态兴,破壞了storyboard的“可視化流程”(visual flow),但是沒有任何實現(xiàn)上的負面影響疟位。后一種做法瞻润,保持了可視化流程,但是需要額外的開發(fā)工作甜刻,因為view不是集成到view controller中的:它只是作為一個組件嵌入進來绍撞,所以view controller必需和它進行交互。

一般的優(yōu)點和缺點

現(xiàn)在我們對“在iOS UI設(shè)計中得院,storyboard何時有用”有了一個大概了解傻铣,在開始了解NIBs前,在過一般storyboard的優(yōu)勢和劣勢

優(yōu)點:性能

你可能會覺得祥绞,加載一個storyboard時非洲,它所有的view controllers會馬上被實例化。然而蜕径,這只是一種抽象两踏,實際實現(xiàn)并非如此,相反兜喻,只是初始(initial)view controller(如果有的話)被創(chuàng)建梦染。其它的view controller動態(tài)地實例化,無論是通過segue虹统,還是代碼實現(xiàn)弓坞。

優(yōu)點:原型

用storyboard可以簡化用戶界面和流程的原型和組織。事實上车荔,一個由views和導(dǎo)航組成的完整渡冻、可工作的原型應(yīng)用程序,用storyboard很容易實現(xiàn)——只需要不多的代碼

缺點:復(fù)用性

對于移動和復(fù)制忧便,storyboard的表現(xiàn)就不太好了族吻。一個storyboard必須和它所依賴的view controllers一起移動。換句話說珠增,一個單獨的view controller不能被單獨抽取出來作為一個單獨的實體在其它地方使用超歌,它依賴于storyboard的其它部分才能工作。

缺點:數(shù)據(jù)流

應(yīng)用程序運行時蒂教,經(jīng)常需要將數(shù)據(jù)在view controller之間傳遞巍举。然而,storyboard的可視化流程在這種情況下會被破壞凝垛,因為在Interface Builder中無法傳數(shù)據(jù)懊悯。storyboard負責(zé)處理view controller之間的切換蜓谋,但卻不處理數(shù)據(jù)流。所以炭分,“目標”controller必須用代碼“配置”桃焕,這樣就破壞了“可視化”。

這些情況下捧毛,我們不得不依賴于prepareForSegue:sender观堂,再加上if/else-if:

(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    NSString *identifier = [segue identifier];
    if ([identifier isEqualToString@"segue_name_1"]) {
        MyViewController *vc = (MyViewController *) [segue destinationViewController];
        [vc setData:myData];
    } else if ([identifier isEqualToString@"segue_name_2"]) {
        ...
    } else if ...
}

我認為這種方式很容易出錯,而且也過于繁瑣呀忧。

NIBs

NIBs是(較)老的設(shè)計UI的方式师痕。

在這里,“老”并不意味著“壞”荐虐、“過時”七兜、“不推薦”。事實上福扬,應(yīng)該深刻理解:storyboard并不是能完全取代NIBs的方式腕铸,它們僅僅是在某些情況下的合適方式。

使用NIB铛碑,一個單獨的view被設(shè)計出來狠裹,然后根據(jù)需要把它“附加”到view controller上去。

如果我們用“面向?qū)ο蟆钡姆绞絹碓O(shè)計UI汽烦,那么就應(yīng)該把view controller’s view拆分成獨立的模塊涛菠,每一個模塊是一個由單獨的NIB文件設(shè)計的view(或者多個模塊組合到同一個文件)。這樣做明顯的優(yōu)勢是:每一個元素都易開發(fā)撇吞、易測試俗冻、易調(diào)試。

NIBs也有像storyboard那樣的“合并沖突”問題牍颈,但相對來說較不嚴重迄薄,因為NIB所操作的范圍要小。

何時用NIBs設(shè)計UI

部分可用的場合如:

  • 模式views【譯者:那些彈出的對話框之類吧】
  • 簡單的登錄煮岁、注冊views
  • 設(shè)置
  • Popup windows
  • 可復(fù)用view模板
  • 可復(fù)用tabel cell模板

然后……

何時不要用NIBs

下面這些情況應(yīng)避免使用NIBs:

  • 如果view中有動態(tài)內(nèi)容讥蔽,且根據(jù)內(nèi)容的不同Layout會有較大差異
  • 如果view天然就不容易用Interface Builder設(shè)計
  • 如果view controllers有復(fù)雜的transition,但用storyboard方式可以簡化
一般的優(yōu)點和缺點

讓我們來看看NIBs的優(yōu)缺點画机。

優(yōu)點:復(fù)用性

如果多個類共用相同的Layout冶伞,那么NIBs是很方便的。

舉個簡單的栗子步氏。
【譯者:這個栗子是關(guān)于登錄和注冊view復(fù)用同一個NIB响禽,因為他們都由username+password組成。不是太會翻譯,故略過】

優(yōu)點(也是缺點):性能

NIBs是“懶加載”金抡,所以直到加載之前是不占內(nèi)存的瀑焦。這是一個優(yōu)勢腌且,但同時梗肝,因為懶加載過程有開銷【這里不太會譯】,所以也是一個劣勢铺董。

代碼(用程序?qū)崿F(xiàn)UI)

任何可以用storyboard或NIBs實現(xiàn)的UI都可以用純代碼實現(xiàn)(當然巫击,曾經(jīng)一度,沒有那么多工具時就是這樣的)

NIBs和storyboard不能實現(xiàn)的精续,都可以用代碼實現(xiàn)坝锰。

也許更重要的是,NIBs和storyboard不能實現(xiàn)的重付,都可以用代碼實顷级。當然,那是代碼的技術(shù)特性确垫。換一個角度弓颈,NIBs和storyboard本身就是代碼實現(xiàn)的,所以它們的功能天然就是代碼全部功能的一個子集∩鞠疲現(xiàn)在直接來看代碼的優(yōu)點和缺點吧翔冀。

優(yōu)點:本質(zhì)

用代碼實現(xiàn)UI的最大的好處是:如果你知道如何用代碼來實現(xiàn)UI,那么你就知道背后發(fā)生的事情披泪,可是NIBs和storyboard卻不一定纤子。

類比一下:計算器是一個有用的工具。但是款票,學(xué)會手工計算也是一個不錯的事控硼。

不只是iOS,任何可視化RAD(Rapid Application Development)工具(比如:Visual Studio艾少、Delphi)卡乾,Visual HTML RAD開發(fā)環(huán)境算是最差的代表:它們可以產(chǎn)生代碼(當然,往往是很差的)姆钉,聲稱“不需要html只是”说订,一切都可以可視化完成。但是潮瓶,沒有一個web程序員能“不用弄臟手”【譯者:指的是不用寫代碼】就可以寫出網(wǎng)頁來陶冷,因為他們知道手寫的html和CSS可以產(chǎn)生更模塊化、更有效的代碼毯辅。

所以埂伦,掌握用代碼構(gòu)建iOS UI可以讓你有更多控制,也更明白各部分是如何拼接起來的思恐,進而提高你作為一個程序員的“上限”

優(yōu)點:但代碼是唯一的選擇時

有一些場景沾谜,只能用代碼構(gòu)建UI膊毁。動態(tài)Layout——可視元素動來動去,Layout根據(jù)內(nèi)容有較大調(diào)整基跑,是典型的例子婚温。

優(yōu)點:合并沖突

NIBs和storyboard飽受合并沖突之苦,而代碼卻完全不受此苦媳否。所有代碼都是有意義的栅螟,所以解決沖突跟其他(代碼沖突)情況是一樣一樣的。

缺點:原型

直到代碼運行起來之前篱竭,你看不到一個Layout長的什么樣力图。更甚,你不能可視化地擺放views和controls掺逼,所以吃媒,將Layout文檔(specs)轉(zhuǎn)為可見的view需要更多時間,而NIBs和storyboard卻可以馬上給你一個可以預(yù)覽的效果吕喘。

缺點:重構(gòu)

重構(gòu)很久之前寫的代碼或別人的代碼——代碼中元素被放置赘那,或動畫時用的自定義的方法或奇怪的數(shù)字,將會是一個很費勁的活兽泄,調(diào)試也一樣費勁漓概。

優(yōu)點:性能

性能方面,NIBs和storyboard是先加載病梢、解析胃珍,最后再翻譯成代碼。不用說蜓陌,代碼構(gòu)建UI不會有此轉(zhuǎn)換過程觅彰。

優(yōu)點:復(fù)用

任何代碼構(gòu)建的view都可以用“可復(fù)用”的方式來實現(xiàn)。來看幾個例子:

  • 兩個或更多views共用一個行為钮热,但又有些微的區(qū)別填抬。可以通過一個基類和兩個派生類來解決此問題隧期,很優(yōu)雅飒责。
  • 有時不得不拆分一個工程,目的是基于同一套代碼仆潮,產(chǎn)生兩個(或更多)不同的應(yīng)用程序宏蛉,每一個有自己特殊的定制【譯者:這個例子有點莫名其妙】

如果是用NIBs或storyboard來實現(xiàn)這同樣的過程,將會復(fù)雜的多性置。模板文件【就是那些定義UI的xml文件吧】不支持繼承拾并,所以可能的解決方案也就是下面這些:

  • 復(fù)制NIB和storyboard文件。從此以后,他們將開始不同的“生命”嗅义,跟原始文件也沒有了關(guān)系屏歹。
  • 用代碼改寫(override)可視效果和行為。這種方式之碗,在簡單情況下或許奏效蝙眶,但復(fù)雜了就可能導(dǎo)致異常的復(fù)雜性。大規(guī)模的override可能導(dǎo)致原先用NIBs或storyboard實現(xiàn)的UI效果完全無用继控,如械馆,某個控件在Interface Builder中表現(xiàn)是一種行為,而在程序運行起來之后卻完全是另外一種行為武通,這時你就會相當頭疼。
何時使用代碼

當有下列情形時珊搀,用代碼是不錯的選擇:

  • 動態(tài)Layout
  • views有諸如圓角冶忱、陰影等特殊效果
  • 其他,如果用NIBs或storyboard會很復(fù)雜或不方便的情況
何時不用代碼

總體來說境析,代碼構(gòu)建UI何時都可以用囚枪。它們“鮮有”成為錯誤選擇的情況。
……

同一個工程劳淆,多種工具

storyboard链沼,NIBs和代碼是構(gòu)建UI的三種不同的工具。很幸運沛鸵,我們都可以選擇括勺。對于堅持只用代碼的那些家伙來說,另外兩個工具根本不會考慮曲掰,因為用代碼可以實現(xiàn)任何技術(shù)上可能的東西疾捍,而另外兩個都有它們的局限性。但對于其他的程序員栏妖,xcode這把“軍刀”提供了三種不同的工具乱豆,而且可以在同一個工程中任意選用。

你會問吊趾,那我怎么選擇宛裕?看你自己喜好吧。這里有一些建議供參考:

  • 將相關(guān)的所有頁面歸到一組(這樣你會有多個組)论泛,每一組實現(xiàn)在獨立的storyboard中
  • 將不可復(fù)用table cells放在storyboard中——table view controller中
  • 將可復(fù)用的table cells放在NIBs中——以鼓勵復(fù)用揩尸,并避免重復(fù)勞動,用代碼來加載這些NIBs
  • 用NIBs來設(shè)計自定義的views孵奶、controls等
  • 用代碼構(gòu)建“很動態(tài)”的views疲酌,更泛一點說,就是不容易用storyboard或NIB是實現(xiàn)的views。

【譯者:下面還有一個簡單的例子朗恳,就不譯了】

譯完此文湿颅,想起自己在實際開發(fā)中的經(jīng)歷,有幾點想說的:

——

主題色的故事

在起初開發(fā)階段粥诫,UI沒有給出主題色油航,我們就是按自己喜歡瞎來的。到了最后才給怀浆,我們只能逐個view檢查谊囚,把NIBs和storyboard中的顏色值替換。這換一遍人還可以承受执赡,就怕那天UI同學(xué)很追求完美镰踏,覺得“咦,這個顏色還是差那么一點點沙合,我再微調(diào)一下吧”奠伪。哥呀,我就崩潰了首懈。

這個故事觸發(fā)我想绊率,還是得寫在代碼中(以這個主題色為例),如果UI要換究履,我只要改一個變量值(一行代碼哦)就夠了滤否。當然,我也沒有辦法抗拒NIBs在設(shè)計簡單最仑、固定頁面時的便利藐俺。于是,我就又引入一個機制:在每一NIB所對應(yīng)的UIView中提供一個機會盯仪,將主題色等這種需要全局統(tǒng)一的UI元素重新設(shè)一次(也就是作者在文中提到的override)紊搪。也就是說,最終在UI上的顯示效果將由此處代碼的設(shè)置為最終結(jié)果全景,NIB文件中的被覆蓋(那就當做程序員開發(fā)過程中的“第一層防銹漆”吧)

適配屏幕的故事

為了適應(yīng)各種size的手機屏耀石,有些頁面得采用“占頁面百分比”的方式來擺放UI元素。這種情況爸黄,只能用code實現(xiàn)了滞伟。因為最終的Point坐標是在運行時計算出來的,用NIB和storyboard是斷不可能實現(xiàn)的炕贵。當然梆奈,這樣的頁面一般也是比較簡單(就是因為UI元素少,才需要根據(jù)屏幕大小調(diào)整一下位置称开、大小等)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亩钟,一起剝皮案震驚了整個濱河市乓梨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌清酥,老刑警劉巖扶镀,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異焰轻,居然都是意外死亡臭觉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門辱志,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝠筑,“玉大人,你說我怎么就攤上這事揩懒∈惨遥” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵旭从,是天一觀的道長稳强。 經(jīng)常有香客問我,道長和悦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任渠缕,我火速辦了婚禮鸽素,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘亦鳞。我一直安慰自己馍忽,他們只是感情好,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布燕差。 她就那樣靜靜地躺著遭笋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪徒探。 梳的紋絲不亂的頭發(fā)上瓦呼,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音测暗,去河邊找鬼央串。 笑死,一個胖子當著我的面吹牛碗啄,可吹牛的內(nèi)容都是我干的质和。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼稚字,長吁一口氣:“原來是場噩夢啊……” “哼饲宿!你這毒婦竟也來了厦酬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘫想,失蹤者是張志新(化名)和其女友劉穎仗阅,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殿托,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡霹菊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了支竹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旋廷。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖礼搁,靈堂內(nèi)的尸體忽然破棺而出饶碘,到底是詐尸還是另有隱情,我是刑警寧澤馒吴,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布扎运,位于F島的核電站,受9級特大地震影響饮戳,放射性物質(zhì)發(fā)生泄漏豪治。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一扯罐、第九天 我趴在偏房一處隱蔽的房頂上張望负拟。 院中可真熱鬧,春花似錦歹河、人聲如沸掩浙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厨姚。三九已至,卻和暖如春键菱,著一層夾襖步出監(jiān)牢的瞬間谬墙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工纱耻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留芭梯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓弄喘,卻偏偏與公主長得像玖喘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蘑志,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

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