代碼不規(guī)范暴拄,同事兩行淚

任何一個傻瓜都能寫出計算機(jī)可以理解的代碼。唯有寫出人類容易理解的代碼氛魁,才是優(yōu)秀的程序員暮顺。 —— 佚名

本文是筆者結(jié)合公司代碼規(guī)范要求,和之前看的《禪與 Objective-C 編程藝術(shù)》與《Effective Objective-C 2.0》書籍秀存,以及參考相關(guān)博客捶码,總結(jié)出的一套iOS開發(fā)規(guī)范。有不足的地方或链,歡迎博客下留言惫恼。

圖片發(fā)自簡書App

大括號

除了 .m 文件中方法,其他的地方大括號"{"不需要另起一行澳盐。推薦:

if (!error) {
    return success;
}

- (void)doHomework
{
    if (self.hungry) {
        return;
    }
    //doSomething
}

運(yùn)算符

1. 一元運(yùn)算符與變量之間沒有空格:

!aValue
-aValue  //負(fù)號
~aValue  //位非
++iCount
*strSource

2. 二元運(yùn)算符與變量之間必須有空格

fWidth = 5 + 5;
fLength = fWidth * 2;
for(int i = 0; i < 10; i++)

3.三元運(yùn)算符
當(dāng)三元運(yùn)算符的第二個參數(shù)(if 分支)返回和條件語句中已經(jīng)檢查的對象一樣的對象的時候尤筐,下面的表達(dá)方式更靈巧:

result = object ? : [self createObject];

不推薦:

result = object ? object : [self createObject];

if語句

1. 盡量列出所有的情況,且給出明確的結(jié)果洞就。

推薦:

var hintStr;
if (count < 3) {
  hintStr = "Good";
} else {
  hintStr = "";
}

2. 黃金大道
在使用條件語句編程時盆繁,代碼的左邊距應(yīng)該是一條“黃金”或者“快樂”的大道,也就是說善于使用return來提前返回不符合的情況旬蟋。

推薦:

- (void)someMethod {
    if (![someOther boolValue]) {
        return;
    }
    // Do something important
}

3. 復(fù)雜的表達(dá)式
條件表達(dá)式如果比較復(fù)雜油昂,則需要將他們提取出來賦給一個BOOL變量。
推薦:

BOOL nameContainsSwift  = [sessionName containsString:@"Swift"];
BOOL isCurrentYear      = [sessionDateCompontents year] == 2019;
BOOL isSwiftSession     = nameContainsSwift && isCurrentYear;

if (isSwiftSession) {
    // Do something very cool
}

4.尤達(dá)表達(dá)式
尤達(dá)表達(dá)式是指倾贰,拿一個常量去和變量比較而不是拿變量去和常量比較夕膀。
推薦:

if (count == 6) {
}
if (myValue == nil) {
}
if (!object ) {
}

不推薦:

if ( 6 == count) {
}
if ( nil == object ) {
}

5. 條件語句體應(yīng)該總是被大括號包圍
盡管有時候你可以不使用大括號(比如烛芬,條件語句體只有一行內(nèi)容),但是這樣做會帶來問題隱患。
推薦:

if (!error) {
  return success;
}

不推薦:

if (!error)
    return success;
if (!error) return success; 

Switch語句

1. 每個分支都必須用大括號括起來

推薦:

switch (integer) {  
  case 1:  {
    // ...  
    break;  
  }
  case 2: {  
    // ...  
    break;  
  }  
  case 3: {
    // ...  
    break; 
  }
  default:{
    // ...  
    break; 
  }
}

2.除了使用枚舉類型以外叛本,都必須有default分支

switch (menuType) {  
  case menuTypeLeft: {
    // ...  
    break; 
   }
  case menuTypeRight: {
    // ...  
    break; 
  }
  case menuTypeTop: {
    // ...  
    break; 
  }
  case menuTypeBottom: {
    // ...  
    break; 
  }
}

在Switch語句使用枚舉類型的時候,如果使用了default分支耙替,在將來就無法通過編譯器來檢查新增的枚舉類型了。


函數(shù)

1. 一個函數(shù)的長度盡量限制在50行以內(nèi)
如果一個方法里面的代碼行數(shù)過多言秸,代碼的閱讀體驗(yàn)極差。

2. 一個函數(shù)只做一件事(單一原則)
每個函數(shù)的職責(zé)都應(yīng)該劃分的很明確(就像類一樣)迎捺。

3. 對于有返回值的函數(shù)举畸,確保每個分支都有返回值

推薦:

int function()
{
    if(condition1){
        return count1
    }else if(condition2){
        return count2
    }else{
       return defaultCount
    } 
}

4. 外部傳入的參數(shù)需要檢驗(yàn)參數(shù)的非空、數(shù)據(jù)類型的合法性凳枝,參數(shù)錯誤立即返回或斷言

推薦:

void function(param1,param2)
{
      if(!param1){
           return;
      }
      if(!param2){
           return;
      }
     //Do some right thing
}

5. 多個函數(shù)如果有邏輯重復(fù)的代碼抄沮,建議將重復(fù)的部分抽取出來,成為獨(dú)立的函數(shù)進(jìn)行調(diào)用

6. 如果方法參數(shù)過多過長岖瑰,建議多行書寫,每個參數(shù)占用一行叛买,用冒號進(jìn)行對齊
推薦:

- (void)initWithAge:(NSInteger)age
               name:(NSString *)name
             weight:(CGFloat)weight;

7. 方法名中不應(yīng)使用and,而且簽名要與對應(yīng)的參數(shù)名保持一致

推薦:

- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

不推薦:

- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;

注釋

1.類的注釋
對于類的注釋寫在當(dāng)前類文件的頂部蹋订。

2.屬性注釋
對于屬性的注釋建議寫在屬性上面率挣,用的時候,會有提示功能辅辩。

/// 刷新按鈕
@property (nonatomic, strong) UIButton *refreshBtn;

3.方法注釋
對于.h文件中方法的注釋难礼,通過快捷鍵command+option+/快速注釋;
對于.m文件中方法的注釋玫锋,在方法的上邊添加//蛾茉,注釋符和注釋內(nèi)容需要間隔一個空格。例如

// load network data

4.功能注釋
版本迭代中撩鹿,在同事寫的代碼基礎(chǔ)上開發(fā)谦炬,一定要寫上版本功能注釋,方便詢問具體功能节沦。推薦

// 這是一個新加的功能 v5.20.0 by minjing.lin

變量

1. 變量名必須使用駝峰格式
類键思,協(xié)議使用大駝峰:

HomePageViewController.h
<HeaderViewDelegate>

對象等局部變量使用小駝峰:

NSString *personName = @"";
NSUInteger totalCount = 0;

2.變量的名稱必須同時包含功能與類型

UIButton *addBtn 
UILabel *nameLbl 
NSString *addressStr

3. 系統(tǒng)常用類作實(shí)例變量聲明時加入后綴

類型 后綴
UIViewController VC
UIView View
UILabel Lbl
UIButton Btn
UIImage Img
UIImageView ImagView
NSArray Arr
NSMutableArray Marr
NSDictionary Dict
NSMutableDictionary Mdict
NSString Str
NSMutableString Mstr
NSSet Set
NSMutableSet Mset

常量

1. 常量以相關(guān)類名作為前綴

推薦:

static const NSTimeInterval ZOCSignInViewControllerFadeOutAnimationDuration = 0.4;

不推薦:

static const NSTimeInterval fadeOutTime = 0.4;

2. 建議使用類型常量,不建議使用#define預(yù)處理命令

首先比較一下這兩種聲明常量的區(qū)別:

  • 預(yù)處理命令:簡單的文本替換甫贯,不包括類型信息吼鳞,并且可被任意修改。
  • 類型常量:包括類型信息叫搁,并且可以設(shè)置其使用范圍赔桌,而且不可被修改。

推薦:

static const CGFloat ZOCImageThumbnailHeight = 50.0f;

不推薦:

#define CompanyName @"Apple Inc." 
#define magicNumber 42 

3. 對外公開某個常量

如果我們需要發(fā)送通知渴逻,那么就需要在不同的地方拿到通知的“頻道”字符串(通知的名稱)疾党,那么顯然這個字符串是不能被輕易更改,而且可以在不同的地方獲取惨奕。這個時候就需要定義一個外界可見的字符串常量雪位。

推薦:

//.h
extern NSString *const ZOCCacheControllerDidClearCacheNotification;
//.m
static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";

1. 字母全部大寫,單詞與單詞之間用_分割

#define URL_GAIN_QUOTE_LIST @"/v1/quote/list"
#define URL_UPDATE_QUOTE_LIST @"/v1/quote/update"

2. 宏定義中如果包含表達(dá)式或變量梨撞,表達(dá)式和變量必須用小括號括起來

#define MY_MIN(A, B)  ((A)>(B)?(B):(A))

枚舉

當(dāng)使用 enum 的時候雹洗,建議使用新的固定的基礎(chǔ)類型定義香罐,因?yàn)樗懈鼜?qiáng)大的類型檢查和代碼補(bǔ)全。

typedef NS_ENUM(NSInteger, UIControlContentVerticalAlignment) {
    UIControlContentVerticalAlignmentCenter  = 0,
    UIControlContentVerticalAlignmentTop     = 1,
    UIControlContentVerticalAlignmentBottom  = 2,
    UIControlContentVerticalAlignmentFill    = 3,
};

范型

建議在定義NSArray和NSDictionary時使用泛型队伟,可以保證程序的安全性:

NSArray<NSString *> *testArr =@[@"hello",@"world"];
NSDictionary<NSString *, NSNumber *> *dic = @{@"key":@(1), @"age":@(10)};

NSMutableArray

1. addObject之前要非空判斷穴吹。

2. 取下標(biāo)的時候要判斷是否越界幽勒。

3. 取第一個元素或最后一個元素的時候使用firtstObject和lastObject


字面量語法

盡量使用字面量值來創(chuàng)建 NSString , NSDictionary , NSArray , NSNumber 這些不可變對象:

推薦:

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"}; 
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018; 

不推薦:

NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill" ];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018]; 


Block

為常用的Block類型創(chuàng)建typedef
如果我們需要重復(fù)創(chuàng)建某種block(相同參數(shù)嗜侮,返回值)的變量,我們就可以通過typedef來給某一種塊定義屬于它自己的新類型啥容。

例如:

int (^variableName)(BOOL flag, int value) =^(BOOL flag, int value)
{
     // Implementation
     return someInt;
}

這個Block有一個bool參數(shù)和一個int參數(shù)锈颗,并返回int類型。我們可以給它定義類型:

typedef int(^EOCSomeBlock)(BOOL flag, int value);

再次定義的時候咪惠,就可以通過簡單的賦值來實(shí)現(xiàn):

EOCSomeBlock block = ^(BOOL flag, int value){
     // Implementation
};

定義作為參數(shù)的Block:

- (void)startWithCompletionHandler: (void(^)(NSData *data, NSError *error))completion;

這里的Block有一個NSData參數(shù)击吱,一個NSError參數(shù)并沒有返回值

typedef void(^EOCCompletionHandler)(NSData *data, NSError *error);
- (void)startWithCompletionHandler:(EOCCompletionHandler)completion;”

通過typedef定義Block簽名的好處是:如果要某種塊增加參數(shù),那么只修改定義簽名的那行代碼即可遥昧。


屬性

1.書寫規(guī)則
@property覆醇、空格、括號炭臭、線程修飾詞永脓、內(nèi)存修飾詞、讀寫修飾詞鞋仍、空格常摧、類、對象名稱威创;
根據(jù)不同的場景選擇合適的修飾符落午。

推薦:

@property (nonatomic, copy, readonly) NSString *name;
@property (nonatomic, strong, readwrite) UIView *headerView;
@property (nonatomic, weak) id<#delegate#> delegate;

2. Block屬性應(yīng)該使用copy關(guān)鍵字

推薦:

typedef void (^ErrorCodeBlock) (id errorCode,NSString *message);
@property (nonatomic, copy) ErrorCodeBlock errorBlock;

@property (nonatomic, copy) <#returnType#> (^<#Block#>)(<#parType#>);

3. 形容詞性的BOOL屬性的getter應(yīng)該加上is前綴

推薦:

@property (nonatomic, assign, getter=isEditable) BOOL editable;

4. 對外盡量使用不可變對象

盡量把對外公布出來的屬性設(shè)置為只讀,在實(shí)現(xiàn)文件內(nèi)部設(shè)為讀寫肚豺。具體做法是:

  • 在頭文件中溃斋,設(shè)置對象屬性為readonly
  • 在實(shí)現(xiàn)文件中設(shè)置為readwrite吸申。

這樣一來梗劫,在外部就只能讀取該數(shù)據(jù),而不能修改它呛谜,使得這個類的實(shí)例所持有的數(shù)據(jù)更加安全在跳。而且,對于集合類的對象隐岛,更應(yīng)該仔細(xì)考慮是否可以將其設(shè)為可變的猫妙。

如果在公開部分只能設(shè)置其為只讀屬性,那么就在非公開部分存儲一個可變型聚凹。所以當(dāng)在外部獲取這個屬性時割坠,獲取的只是內(nèi)部可變型的一個不可變版本,例如:

在公共API中:

@interface EOCPerson : NSObject

@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;
@property (nonatomic, strong, readonly) NSSet *friends //向外公開的不可變集合

- (id)initWithFirstName:(NSString*)firstName andLastName:(NSString*)lastName;
- (void)addFriend:(EOCPerson*)person;
- (void)removeFriend:(EOCPerson*)person;

@end

在這里齐帚,我們將friends屬性設(shè)置為不可變的set。然后彼哼,提供了來增加和刪除這個set里的元素的公共接口对妄。

在實(shí)現(xiàn)文件里:


@interface EOCPerson ()

@property (nonatomic, copy, readwrite) NSString *firstName;
@property (nonatomic, copy, readwrite) NSString *lastName;

@end

@implementation EOCPerson {
     NSMutableSet *_internalFriends;  //實(shí)現(xiàn)文件里的可變集合
}

- (NSSet*)friends 
{
     return [_internalFriends copy]; //get方法返回的永遠(yuǎn)是可變set的不可變型
}

- (void)addFriend:(EOCPerson*)person 
{
    [_internalFriends addObject:person]; //在外部增加集合元素的操作
    //do something when add element
}

- (void)removeFriend:(EOCPerson*)person 
{
    [_internalFriends removeObject:person]; //在外部移除元素的操作
    //do something when remove element
}

- (id)initWithFirstName:(NSString*)firstName andLastName:(NSString*)lastName 
{

     if ((self = [super init])) {
        _firstName = firstName;
        _lastName = lastName;
        _internalFriends = [NSMutableSet new];
    }
 return self;
}

我們可以看到,在實(shí)現(xiàn)文件里敢朱,保存一個可變set來記錄外部的增刪操作剪菱。

這里最重要的代碼是:

- (NSSet*)friends 
{
   return [_internalFriends copy];
}

這個是friends屬性的獲取方法:它將當(dāng)前保存的可變set復(fù)制了一不可變的set并返回。因此拴签,外部讀取到的set都將是不可變的版本孝常。


代理方法

1. 代理方法的第一個參數(shù)必須為委托者

代理方法必須以委托者作為第一個參數(shù)(參考UITableViewDelegate)的方法。其目的是為了區(qū)分不同委托著的實(shí)例蚓哩。因?yàn)橥粋€控制器是可以作為多個tableview的代理的构灸。例如:

-  (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath

2.向代理發(fā)送消息時需要判斷其是否實(shí)現(xiàn)該方法

推薦:

if ([self.delegate respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) { 
 [self.delegate signUpViewControllerDidPressSignUpButton:self]; 
} 

3. 遵循代理過多的時候,換行對齊顯示
推薦:

@interface ShopViewController () <UIGestureRecognizerDelegate,
                                  HXSClickEventDelegate,
                                  UITableViewDelegate,
                                  UITableViewDataSource>

4. 代理的方法需要明確必須執(zhí)行和可不執(zhí)行

  • @required:必須實(shí)現(xiàn)的方法
  • @optional:可選是否實(shí)現(xiàn)的方法
@protocol ZOCServiceDelegate <NSObject>
@optional
- (void)generalService:(ZOCGeneralService *)service didRetrieveEntries:(NSArray *)entries; 
@end 


1. 類的名稱
應(yīng)該以三個大寫字母為前綴岸梨;創(chuàng)建子類的時候喜颁,應(yīng)該把代表子類特點(diǎn)的部分放在前綴和父類名的中間。

推薦:

//父類
ZOCSalesListViewController

//子類
ZOCDaySalesListViewController
ZOCMonthSalesListViewController

2. 所有返回類對象和實(shí)例對象的方法都應(yīng)該使用instancetype

將instancetype關(guān)鍵字作為返回值的時候曹阔,可以讓編譯器進(jìn)行類型檢查半开,同時適用于子類的檢查,這樣就保證了返回類型的正確性(一定為當(dāng)前的類對象或?qū)嵗龑ο螅?/p>

推薦:

- (instancetype)init 
{ 
    self = [super init]; // call the designated initializer 
    if (self) { 
        // Custom initialization 
    } 
    return self; 
} 

@interface ZOCPerson
+ (instancetype)personWithName:(NSString *)name; 
@end 

不推薦:

@interface ZOCPerson
+ (id)personWithName:(NSString *)name; 
@end 

3. 在類的.h文件中盡量少引用其他頭文件

有時次兆,類A需要將類B的實(shí)例變量作為它公共API的屬性稿茉。這個時候,我們不應(yīng)該引入類B的頭文件芥炭,而應(yīng)該使用向前聲明(forward declaring)使用class關(guān)鍵字漓库,并且在A的實(shí)現(xiàn)文件引用B的頭文件。

// EOCPerson.h
#import <Foundation/Foundation.h>

@class EOCEmployer;

@interface EOCPerson : NSObject

@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) EOCEmployer *employer;//將EOCEmployer作為屬性

@end

// EOCPerson.m
#import "EOCEmployer.h"

優(yōu)點(diǎn):

  • 不在A的頭文件中引入B的頭文件园蝠,就不會一并引入B的全部內(nèi)容渺蒿,這樣就減少了編譯時間。

  • 可以避免循環(huán)引用:因?yàn)槿绻麅蓚€類在自己的頭文件中都引入了對方的頭文件彪薛,那么就會導(dǎo)致其中一個類無法被正確編譯茂装。

但是個別的時候,必須在頭文件中引入其他類的頭文件:

  • 該類繼承于某個類善延,則應(yīng)該引入父類的頭文件少态。
  • 該類遵從某個協(xié)議,則應(yīng)該引入該協(xié)議的頭文件易遣。而且最好將協(xié)議單獨(dú)放在一個頭文件中彼妻。

4. 類的布局

#pragma mark - Life Cycle Methods
- (instancetype)init
- (void)dealloc

- (void)viewWillAppear:(BOOL)animated
- (void)viewDidAppear:(BOOL)animated
- (void)viewWillDisappear:(BOOL)animated
- (void)viewDidDisappear:(BOOL)animated

#pragma mark - Override Methods

#pragma mark - Network Methods

#pragma mark - Target Methods

#pragma mark - Public Methods

#pragma mark - Private Methods

#pragma mark - UITableViewDataSource  
#pragma mark - UITableViewDelegate  

#pragma mark - Setters and Getters

可以使用代碼塊一鍵生成,參考Xcode 快速開發(fā) 代碼塊


相等性的判斷

判斷兩個person類是否相等的合理做法:

-  (BOOL)isEqual:(id)object 
{

    if (self == object) {  
        return YES; //判斷內(nèi)存地址
    } 

    if (![object isKindOfClass:[ZOCPerson class]]) { 
        return NO; //是否為當(dāng)前類或派生類 
     } 

     return [self isEqualToPerson:(ZOCPerson *)object]; 

}

//自定義的判斷相等性的方法
-  (BOOL)isEqualToPerson:(Person *)person 
{ 
        if (!person) {  
              return NO;
        } 
        BOOL namesMatch = (!self.name && !person.name) || [self.name isEqualToString:person.name]; 
        BOOL birthdaysMatch = (!self.birthday && !person.birthday) || [self.birthday isEqualToDate:person.birthday]; 
        return haveEqualNames && haveEqualBirthdays; 
} 


圖片命名

1.命名規(guī)范:不能有中文、大寫侨歉、特殊符號屋摇、空白
2.命名格式(推薦):
fileType[function]project[pageName]imageName[status]{.png,@2x.png,@3x.png}
萬能公式:類別_功能_模塊_頁面_名稱_狀態(tài).png

icon_tab_bookshelf_sel@2x.png

面試題(風(fēng)格糾錯)

typedef  enum{
    UserSex_Man,
    UserSex_Woman
}UserSex;
@interface UserModel :NSObject

@property(nonatomic, strong) NSString *name;
@property (assign,nonatomic) int age;
@property (nonatomic,assign) UserSex sex;

-(id)initUserModelWithUserName: (NSString*)name withAge(int age);

-(void)doLogIn;
@end

參考文獻(xiàn):

禪與 Objective-C 編程藝術(shù)
iOS 代碼規(guī)范
看完這個你們團(tuán)隊(duì)的代碼也很規(guī)范
《Effective Objective-C 2.0》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幽邓,隨后出現(xiàn)的幾起案子炮温,更是在濱河造成了極大的恐慌,老刑警劉巖牵舵,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柒啤,死亡現(xiàn)場離奇詭異,居然都是意外死亡棋枕,警方通過查閱死者的電腦和手機(jī)白修,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門妒峦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來重斑,“玉大人,你說我怎么就攤上這事肯骇】耍” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵笛丙,是天一觀的道長漾脂。 經(jīng)常有香客問我,道長胚鸯,這世上最難降的妖魔是什么骨稿? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮姜钳,結(jié)果婚禮上坦冠,老公的妹妹穿的比我還像新娘。我一直安慰自己哥桥,他們只是感情好辙浑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拟糕,像睡著了一般判呕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上送滞,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天侠草,我揣著相機(jī)與錄音,去河邊找鬼犁嗅。 笑死边涕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的愧哟。 我是一名探鬼主播奥吩,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼哼蛆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霞赫?” 一聲冷哼從身側(cè)響起腮介,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎端衰,沒想到半個月后叠洗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旅东,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年灭抑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抵代。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡腾节,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荤牍,到底是詐尸還是另有隱情案腺,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布康吵,位于F島的核電站劈榨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏晦嵌。R本人自食惡果不足惜同辣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惭载。 院中可真熱鬧旱函,春花似錦、人聲如沸棕兼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伴挚。三九已至靶衍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茎芋,已是汗流浹背颅眶。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留田弥,地道東北人涛酗。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親商叹。 傳聞我的和親對象是個殘疾皇子燕刻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

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