iOS開發(fā)代碼編寫規(guī)范簡單總結(jié)

隨著代碼量的增加和項(xiàng)目的增大以及項(xiàng)目合理或不合理的迭代背镇,代碼會(huì)顯得冗余和雜亂。良好的代碼規(guī)范和和規(guī)則以及設(shè)計(jì)良好的封裝對(duì)項(xiàng)目的迭代擴(kuò)展以及程序員本身無疑是一件好事丰刊,但是事實(shí)是被大多數(shù)程序員忽略隘谣,下面是自己對(duì)自己的一點(diǎn)代碼規(guī)范要求

  • <span id="使用屬性_ref_id">使用屬性</span>

從C++的官方推薦和Java Bean規(guī)范來講,都是把變量私有化啄巧,對(duì)外提供getter和setter方法寻歧,這就是我們常說的“屬性”,對(duì)于Objective-C的優(yōu)雅的屬性語法秩仆,我們更應(yīng)該在可以使用變量和屬性的選擇中優(yōu)先選擇屬性码泛,即:

不要使用

@interface MyObject : NSObject {
  NSString *name;
    ...
}
@end

應(yīng)該使用

@interface MyObject : NSObject
  
@property (nonatomic, copy) NSString *name;
@end

使用這種命令方式的優(yōu)點(diǎn)不僅僅在于統(tǒng)一了代碼規(guī)范,而且更重要的是由于提供了setter/getter方法逗概,可以更好的保護(hù)數(shù)據(jù)弟晚,以及在set/get的時(shí)候作額外的操作,并且使用@property的形式方便運(yùn)行時(shí)捕捉到屬性信息以便作底層次的處理逾苫。

但是卿城,可能有人問使用變量會(huì)不會(huì)比使用屬性效率要高?回答:很可能是铅搓,所以你寫項(xiàng)目全用匯編或機(jī)器語言寫好了瑟押,不要考慮其他語言。為了這一點(diǎn)點(diǎn)所謂的效率而失掉優(yōu)雅的代碼特性是錯(cuò)誤的做法星掰。而且可以負(fù)責(zé)任的說多望,真正的coding高手眼中的效率問題絕不是這種淺薄的棄掉屬性用變量換取執(zhí)行效率的問題。

  • <span id="ARC中屬性的省略寫法_ref_id">ARC中屬性的省略寫法</span>

    ARC自從推出至今已很多年氢烘,我們的項(xiàng)目一律采用ARC內(nèi)存管理方式處理怀偷。

    在ARC中屬性默認(rèn)為strong,這個(gè)字段可以省略不寫播玖,即:

    不要使用:

    @property (nonatomic, strong) Person *person;
    

    建議使用:

    @property (nonatomic) Person *person;
    

    對(duì)于基本類型同樣可以省略assign椎工,因?yàn)閷?duì)于基本數(shù)據(jù)類型,不存在什么strong或retain:

    不要使用:

    @property (nonatomic, assign) NSInteger age;
    

    建議使用:

    @property (nonatomic) NSInteger age;
    

    在一些第三方庫的代碼里,可能見到省略的或不省略的寫法维蒙,在這里掰吕,咱們只是為了統(tǒng)一規(guī)范而已,無用與不用的理由颅痊。

  • <span id="屬性的統(tǒng)一寫法_ref_id">屬性的統(tǒng)一寫法</span>

    @property (nonatomic) Person *person;
    

    @property的括號(hào)間有間隔殖熟,nonatomic和strong間有間隔,指針*號(hào)靠近對(duì)象而不是靠近類斑响。

    只是為了清晰代碼和規(guī)范菱属,無用與不用的理由。

  • <span id="屬性的一些使用技巧_ref_id">屬性的一些使用技巧</span>

    在自己封裝一些類庫時(shí)恋捆,屬性的寫法有些注意事項(xiàng):

    • 不必要提供出去的屬性寫在.m中照皆,形如:

      // MyClass.m
      @interface MyClass()
      
      @property (nonatomic) SomeObject *obj; // 既然沒必要提供出去,就把它私有化沸停,外界不讓訪問
      @end
      
      @implementation MyClass
      ...
      @end
      
    • 提供出去的BOOL類型的屬性膜毁,其getter方法寫為:isXxx, 形如:

      @property (nonatomic, getter=isValid) BOOL valid; 
      // 這樣調(diào)用set方法為:obj.valid = YES; 
      // 調(diào)用get方法為:BOOL isValid = obj.isValid;
      

      這種方式更貼近人性化,我們看Apple的官方類愤钾,對(duì)于這類BOOL類型的屬性瘟滨,也是如此,比如:

      // UIKit/UIControl.h
      @property(nonatomic,getter=isEnabled) BOOL enabled;
      @property(nonatomic,getter=isSelected) BOOL selected;
      
    • 一些屬性在外部只讀能颁,但在內(nèi)部需要set的做法:

      // MyClass.h
      @interface MyClass : NSObject
      
      @property (nonatomic, readonly) SomeObject *obj; // 對(duì)外只讀
      @end
      
      // MyClass.m
      @interface MyClass()
      
      @property (nonatomic, readwrite) SomeObject *obj;
      @end
      
      @implementation MyClass
      - (void)myMethod {
          self.obj = [[SomeObject alloc] init]; // 在內(nèi)部可以賦值
      }
      @end
      
      

      ?

  • <span id="駝峰命名法_ref_id">駝峰命名法</span>

    駝峰命名法Camel-Case從早期的lower-case命名法發(fā)展而來杂瘸,形如“好學(xué)生”的lower-case命名法為:good_student, 其駝峰命名法為:goodStudent, 這些都被大家所習(xí)慣和熟識(shí),在OC中伙菊,類名第一個(gè)字母必須大寫败玉,變量第一個(gè)字母小寫等規(guī)則不必多說,但值得一提的是

    不要使用:

    Student *gS;
    

    建議使用:

    Student *goodStudent;
    

    在像Objective-C類似的這種高級(jí)語言中镜硕,絕不建議過分的省略單詞的寫法运翼,如果寫成gS, 只有你和鬼知道是什么意思,多打一點(diǎn)字清晰一些不是什么壞事兴枯。有位老師在教授PHP的課堂中曾說到一個(gè)學(xué)生起的變量名為:fdckfs, 后來一問才知道這個(gè)意思是”房地產(chǎn)開發(fā)商“血淌。

  • <span id="類中屬性/變量的多余寫法_ref_id">類中屬性/變量的多余寫法</span>

    比如學(xué)生類:Student, 有兩個(gè)屬性:姓名和年齡

    不要使用:

    @property (nonatomic, copy) NSString *studentName;
    @property (nonatomic) NSInteger studentAge;
    

    建議使用:

    @property (nonatomic, copy) NSString *name;
    @property (nonatomic) NSInteger age;
    

    適當(dāng)想一下就可以知道,在學(xué)生類里财剖,name就是學(xué)生的名字悠夯,沒必要再強(qiáng)調(diào)用studentName表示學(xué)生姓名,在Student里用studentName表示學(xué)生姓名是一種完全多余的寫法躺坟。

  • <span id="方法的命名規(guī)則_ref_id">方法的命名規(guī)則</span>

    不必多說沦补,仿官方形式:

    - (void)viewDidLoad {
      // ...
    }
    

    -或+距擴(kuò)號(hào)有一個(gè)空格,方法名駝峰寫法咪橙,首字母一律小寫策彤。

  • <span id="方法的書寫和注釋_ref_id">方法的書寫和注釋</span>

    -方法和+方法栓袖,-/+符合和括號(hào)留空隔,方法體左括號(hào)靠近代碼書寫店诗,for循環(huán);內(nèi)留空隔,形如:

    - (void)viewDidLoad {
      // ...
          for (NSInteger i = 0; i < 100; i++) {
          // ...
          }
    }
    

    其實(shí)和官方API寫法一致而已音榜,養(yǎng)成習(xí)慣庞瘸,統(tǒng)一起來不致看著亂。

    注釋采取Apple推薦注釋赠叼,形如:

    /**
     *  @param keyValues 字典(可以是NSDictionary擦囊、NSData、NSString)
     *  @cls 即data所對(duì)應(yīng)的類瞬场,如果傳為nil, 則不對(duì)data進(jìn)行解析
     *  @return 新建的CommonModel對(duì)象
     */
    + (instancetype)commonModelWithKeyValues:(id)keyValues dataClass:(Class)cls;
    

    對(duì)于//注釋,//符合和注釋文字間留出一個(gè)空隔, 這也是官方的寫法贯被,形如:

    [obj testMethod]; // 這是注釋文字妆艘,和//符合留一空格
    
  • <span id="擴(kuò)展類的方法命名注意事項(xiàng)_ref_id">擴(kuò)展類的方法命名注意事項(xiàng)</span>

    我們看一些第三方庫,比如SDWebImage, MJExtension這些比較特殊批旺,它們很多是擴(kuò)展類Category,比如SDWebImage中有對(duì)UIImageView的擴(kuò)展汽煮,MJExtension有對(duì)NSObject的擴(kuò)展搏熄。拿SDWebImage中的UIImageView+WebCache.h中的方法聲明中示例:

    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
    

    它的命名方式為什么加了前綴sd_, 這不符合一般的方法命名規(guī)范,其實(shí)這主要是為了防止有一天系統(tǒng)給UIImageView也加了setImageWithURL:placeholderImage:或是為了防止其他第三方庫也實(shí)現(xiàn)了setImageWithURL:placeholderImage:這個(gè)方法暇赤。

    這種事情的發(fā)生并不是什么巧合心例,比如我在AFNetworking的UIImageView+AFNetworking中也發(fā)現(xiàn)了類似的代碼:

    - (void)setImageWithURL:(NSURL *)url placeholderImage:(nullable UIImage *)placeholderImage;
    

    如果SDWebImage沒有加前綴,那么這兩個(gè)方法的方法簽名就都是:setImageWithURL:placeholderImage:

    試想翎卓,在這兩個(gè)庫中契邀,這個(gè)方法都是對(duì)UIImageView的Category,如果SDWebImage真的沒有對(duì)方法加sd_前綴(早版本的SDWebImage確實(shí)沒有加前綴)失暴,在項(xiàng)目中引入SDWebImage這個(gè)庫的同時(shí)又引入了AFNetworking, 會(huì)怎么樣坯门?這就會(huì)出現(xiàn)蘋果官網(wǎng)上說的“Undefined problem”未知問題。

    啟示:如果我們要封裝自己的Category, 方法名也要加自己的統(tǒng)一前綴逗扒。因?yàn)镃ategory不同于繼承古戴,對(duì)于繼承出來的兩個(gè)類,其對(duì)象調(diào)用相同的實(shí)例方法不會(huì)有什么問題矩肩,但Category不一樣现恼,比如上面對(duì)imageView如果調(diào)用相同的方法,編譯器就無法識(shí)別了。

  • <span id="類的命名規(guī)范_ref_id">類的命名規(guī)范</span>

    在傳統(tǒng)的C++語言叉袍、高級(jí)的Java始锚、C#語言中為了解決類名的重復(fù)問題采用了"命名空間"或"package"的方法來解決,大致意思是說在命名空間UI下的Button類和命名空間LB(聯(lián)璧)下的Button類以及其他命名空間下的Button類不是同一個(gè)類喳逛,不同命名空間下可以有相同的類名瞧捌,這好比上海市的“小明”和蘇州市的“小明”不是一個(gè)小明一樣,但可惜的是润文,OC并沒有這樣的機(jī)制姐呐,因此取而代之的是在類名前加前綴,隨著一門語言體系的增大典蝌,我個(gè)人認(rèn)為這種在類名加前綴的做法并不是非常的好曙砂,但好在Apple給我們封裝的類都很經(jīng)典和強(qiáng)悍,在類名前加前綴也使用這些類的用處明顯骏掀。所以毫無疑問鸠澈,我們的項(xiàng)目也要保持這種習(xí)慣。

    按照傳統(tǒng)的MVC模式來分砖织,統(tǒng)一起見類名前加前綴如下:

    Model: LB...
    View: LV...
    Controller: LC...
    
  • <span id="使用屬性_ref_id">枚舉寫法</span>

    OC自定義了枚舉的寫法侧纯,可以很好的聲明枚舉的類型眶熬,比如枚舉類型為NSInteger, 所以

    不建議使用:

    typedef enum {
        LVStyleActionSheet = 0,
        LVStyleAlert
    } LVStyle;
    

    建議使用:

    typedef NS_ENUM(NSInteger, LVStyle) {
        LVStyleActionSheet = 0,
        LVStyleAlert
    };
    
  • <span id="兩種block的常規(guī)寫法_ref_id">兩種block的常規(guī)寫法</span>

    "返回值為void,沒有跟參數(shù)的block類型"拳缠,Apple已經(jīng)為我們定義好了:

    typedef void (^dispatch_block_t)(void);
    

    為了統(tǒng)一起見窟坐,關(guān)于這種block類型哲鸳,項(xiàng)目中也應(yīng)該用dispatch_block_t徙菠,因?yàn)槌S玫脑蛐霰迹珹pple寫好了這個(gè)類型,另外還有一種block類型常用:"返回值為void挤茄,跟一個(gè)參數(shù)的block類型"驮樊,所以我們可以把這兩種常用的block類型寫進(jìn)pch文件,形如:

    typedef dispatch_block_t BlockVoidType;  // 只是為了向駝峰命名靠近雕沿,重新typedef系統(tǒng)類型
    typedef typedef void (^BlockIdType)(id); // 返回值為void, 跟一個(gè)id參數(shù)的block類型
    
  • <span id="少用tag值_ref_id">少用tag值</span>

    項(xiàng)目中如果有多個(gè)類似的控件审轮,很多情況可以用tag值區(qū)分疾渣,比如一個(gè)頁面有10個(gè)按鈕榴捡,每點(diǎn)擊一個(gè)按鈕把其中一個(gè)學(xué)生的信息傳給其他控制器吊圾,它們觸發(fā)的方法都是buttonClick: 那么為了區(qū)分是哪個(gè)按鈕, 可以用tag值區(qū)分项乒,代碼形如:

    - (void)buttonClick:(UIButton *)button {
      if (button.tag == 100) {
              Student *student = self.studentArray[button.tag-100];
          // ...
      } else if (button.tag == 101) {
              // ..
      }
          ...
    }
    

    這種是極其糟糕的做法檀何,這種寫法除了自己很少有人知道tag為100代表的是什么频鉴,一般來說我們的做法有兩種砚殿,一是封裝自己的Button:

    @interface MyButton
      @property (nonatomic) Student *student;
      // ...
    @end
    

    但是如果項(xiàng)目已寫成似炎,大量的修改這種代碼并不見得好羡藐,所以我們采用第二種方式:

    二是對(duì)Button進(jìn)行擴(kuò)展仆嗦,通過動(dòng)態(tài)關(guān)聯(lián)讓UIButton具有Student屬性瘩扼,針對(duì)這種需求集绰,為了統(tǒng)一起見,在項(xiàng)目中我們對(duì)NSObject進(jìn)行擴(kuò)展給其附加一個(gè)對(duì)象:

    // NSObject+LBAttatchObject.h
    #import <Foundation/Foundation.h>
    
    @interface NSObject (LBAttatchObject)
    
    @property (nonatomic) id lbAttachObject;
    @end
    
    #import "NSObject+LBAttatchObject.h"
    #import <objc/runtime.h>
    
    @implementation NSObject (LBAttatchObject)
    
    - (id)lbAttachObject {
        return objc_getAssociatedObject(self, _cmd);
    }
    
    - (void)setLbAttachObject:(id)lbAttachObject {
        objc_setAssociatedObject(self, @selector(lbAttachObject), lbAttachObject, OBJC_ASSOCIATION_RETAIN);
    }
    
    @end
    
  • <span id="統(tǒng)一模型層_ref_id">統(tǒng)一模型層</span>

    用AF從服務(wù)器上down下來數(shù)據(jù)之后,用MJExtension或其他第三方庫的反射機(jī)制把數(shù)據(jù)轉(zhuǎn)換成模型浴讯,盡量不要使用從字典中取key-value值蔼啦,把數(shù)據(jù)對(duì)象化询吴,為了便于處理,在MJ的基礎(chǔ)上做CommonModel, 統(tǒng)一處理服務(wù)器返回的數(shù)據(jù)

    // LBCommonModel作為整個(gè)App的Model唠摹,不同點(diǎn)在于data字段
    @interface LBCommonModel : NSObject
    
    @property (nonatomic, copy) NSString *msg;
    @property (nonatomic) id data;
    @property (nonatomic) NSInteger code;
    @property (nonatomic, copy) NSString *totalAmt;
    
    /**
     *  @param keyValues 字典(可以是NSDictionary、NSData盗温、NSString)
     *  @cls 即data所對(duì)應(yīng)的類卖局,如果傳為nil, 則不對(duì)data進(jìn)行解析
     *  @return 新建的CommonModel對(duì)象
     */
    + (instancetype)commonModelWithKeyValues:(id)keyValues dataClass:(Class)cls;
    @end
    
  • <span id="Controller命名可去掉View_ref_id">Controller命名可去掉View</span>

    前面說過批销,控制器前綴字符:LC, 如果所有的控制器再加上ViewController, 顯得有些長,比如:LCFinalcialViewController, 為了統(tǒng)一起見丘逸,即然是控制器,突出Controller, 不用帶View, 即命名控制器格式為:

    LCXxxController
    LCFinalcialViewController -> LCFinalcialController
    
  • <span id="慎用通知_ref_id">慎用通知</span>

    通知NSNotificationCenter是KVO設(shè)計(jì)模式的重要實(shí)現(xiàn)之一劲妙,但對(duì)于一般的界面之間的回調(diào)等涛舍,少用通知,通知會(huì)導(dǎo)致系統(tǒng)的維護(hù)性很差肛搬,一旦通知用的多了温赔,很難知道哪里注冊(cè)了通知陶贼,哪里受通知的影響拜秧,這會(huì)變的雜亂枉氮。

    通知應(yīng)當(dāng)用在系統(tǒng)層次聊替、全局層次的影響上惹悄,比如統(tǒng)一處理鍵盤遮擋輸入框的問題泣港,而不是用在簡單的傳值上面爷速。為了更有效的管理通知惫东,統(tǒng)一封裝類LBNotificationManager來管理系統(tǒng)上所有的通知颓遏。形如:

    ace LBNotificationManaager : NSObject
      
    // 通知
    + (void)registNotifyOfDownloadSoftSuccess:(id)observer selector:(SEL)selector; // 注冊(cè)通知
    + (void)postNotifyOfDownloadSoftSuccess:(id)object userInfo:(NSDictionary *)userInfo; // 發(fā)送通知
    + (void)removeNotifyOfDownloadSoftSuccess:(id)observer object:(id)obj; // 取消通知
    @end
    
  • <span id="表單數(shù)據(jù)的抓取_ref_id">表單數(shù)據(jù)的抓取</span>

    在傳統(tǒng)的web開發(fā)中滞时,表單form提供給用戶填寫信息,當(dāng)點(diǎn)擊提交submit的時(shí)候坪稽,再把用戶填寫的表單數(shù)據(jù)提交給服務(wù)器曼玩,在iOS開發(fā)中,我們姑且認(rèn)為諸如UITextField等控件為表單控件窒百,當(dāng)點(diǎn)擊"注冊(cè)黍判、登錄"等提交按鈕時(shí),我們通常做法是從這些控件中提取出值然后做處理篙梢,比如賦值給模型顷帖,過濾一些信息,針對(duì)這種需求渤滞,我們可以做些處理贬墩,點(diǎn)擊提交時(shí)陶舞,讓輸入控件的值自動(dòng)賦給模型颁井,而不必每次再從控件中取值葵硕。

    這里有一個(gè)笨拙的方案: ZZBindDemo_2,但這種處理方式還是比較笨的,如果結(jié)合思路用RAC處理會(huì)好很多,推薦使用RAC解決這個(gè)問題喂很,參照當(dāng)前目錄下 BindDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末煎殷,一起剝皮案震驚了整個(gè)濱河市弓乙,隨后出現(xiàn)的幾起案子懈玻,更是在濱河造成了極大的恐慌湾盒,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汛闸,死亡現(xiàn)場離奇詭異贼急,居然都是意外死亡逗噩,警方通過查閱死者的電腦和手機(jī)残邀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門蹋砚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秧饮,“玉大人,你說我怎么就攤上這事扣蜻。” “怎么了溪烤?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長全陨。 經(jīng)常有香客問我枢舶,道長陡蝇,這世上最難降的妖魔是什么登夫? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮允趟,結(jié)果婚禮上恼策,老公的妹妹穿的比我還像新娘。我一直安慰自己潮剪,他們只是感情好涣楷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抗碰,像睡著了一般狮斗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弧蝇,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天碳褒,我揣著相機(jī)與錄音折砸,去河邊找鬼。 笑死沙峻,一個(gè)胖子當(dāng)著我的面吹牛睦授,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播专酗,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼睹逃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了祷肯?” 一聲冷哼從身側(cè)響起沉填,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎佑笋,沒想到半個(gè)月后翼闹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒋纬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年猎荠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜀备。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡关摇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碾阁,到底是詐尸還是另有隱情输虱,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布脂凶,位于F島的核電站宪睹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蚕钦。R本人自食惡果不足惜亭病,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘶居。 院中可真熱鬧罪帖,春花似錦、人聲如沸邮屁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽樱报。三九已至,卻和暖如春泞当,著一層夾襖步出監(jiān)牢的瞬間迹蛤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盗飒,地道東北人嚷量。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像逆趣,于是被迫代替她去往敵國和親蝶溶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

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