iOS開發(fā)規(guī)范

前 言

  • 需求是暫時(shí)的靠汁,只有變化才是永恒的哺窄,面向變化編程躲庄,而不是面向需求編程圣贸。
  • 不要過(guò)分追求技巧成洗,降低程序的可讀性课梳。
  • 簡(jiǎn)潔的代碼可以讓bug無(wú)處藏身仓洼。要寫出明顯沒有bug的代碼宦言,而不是沒有明顯bug的代碼公壤。
  • 先把眼前的問(wèn)題解決掉换可,解決好,再考慮將來(lái)的擴(kuò)展問(wèn)題厦幅。
    一锦担、命名規(guī)范
    1、統(tǒng)一要求
    含義清楚慨削,盡量做到不需要注釋也能了解其作用洞渔,若做不到套媚,就加注釋,使用全稱磁椒,不使用縮寫堤瘤。
    2、類名
    大駝峰式命名:每個(gè)單詞的首字母都采用大寫字母
    ==例:== MFHomePageViewController
    3浆熔、私有變量
  • 私有變量放在 .m 文件中聲明
  • 以 _ 開頭本辐,第一個(gè)單詞首字母小寫,后面的單詞的首字母全部大寫医增。
    ==例:== NSString *_somePrivateVariable
    4慎皱、property變量
  • 小駝峰式命名:第一個(gè)單詞以小寫字母開始,后面的單詞的首字母全部大寫
  • 屬性的關(guān)鍵字推薦按照 原子性叶骨,讀寫茫多,內(nèi)存管理的順序排列。
  • Block忽刽、NSString屬性應(yīng)該使用copy關(guān)鍵字
  • 禁止使用synthesize關(guān)鍵詞
    ==例:==
    typedef void (^ErrorCodeBlock) (id errorCode,NSString *message);
    @property (nonatomic, readwrite, strong) UIView *headerView; //注釋
    @property (nonatomic, readwrite, copy) ErrorCodeBlock errorBlock; //將block拷貝到堆中
    @property (nonatomic, readwrite, copy) NSString *userName;
    5天揖、宏和常量命名
  • 對(duì)于宏定義的常量
    • define 預(yù)處理定義的常量全部大寫,單詞間用 _ 分隔

    • 宏定義中如果包含表達(dá)式或變量跪帝,表達(dá)式或變量必須用小括號(hào)括起來(lái)今膊。
  • 對(duì)于類型常量
    • 對(duì)于局限于某編譯單元(實(shí)現(xiàn)文件)的常量,以字符k開頭伞剑,例如kAnimationDuration斑唬,且需要以static const修飾
    • 對(duì)于定義于類頭文件的常量,外部可見黎泣,則以定義該常量所在類的類名開頭恕刘,例如EOCViewClassAnimationDuration, 仿照蘋果風(fēng)格,在頭文件中進(jìn)行extern聲明聘裁,在實(shí)現(xiàn)文件中定義其值
      ==例:==
      //宏定義的常量

define ANIMATION_DURATION 0.3

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

//局部類型常量
static const NSTimeInterval kAnimationDuration = 0.3;
//外部可見類型常量
//EOCViewClass.h
extern const NSTimeInterval EOCViewClassAnimationDuration;
extern NSString *const EOCViewClassStringConstant; //字符串類型
//EOCViewClass.m
const NSTimeInterval EOCViewClassAnimationDuration = 0.3;
NSString *const EOCViewClassStringConstant = @"EOCStringConstant";
6雪营、Enum

  • Enum類型的命名與類的命名規(guī)則一致
  • Enum中枚舉內(nèi)容的命名需要以該Enum類型名稱開頭
  • NS_ENUM定義通用枚舉,NS_OPTIONS定義位移枚舉
    ==例:==
    typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    UIViewAnimationTransitionFlipFromLeft,
    UIViewAnimationTransitionFlipFromRight,
    UIViewAnimationTransitionCurlUp,
    UIViewAnimationTransitionCurlDown,
    };
    typedef NS_OPTIONS(NSUInteger, UIControlState) {
    UIControlStateNormal = 0,
    UIControlStateHighlighted = 1 << 0,
    UIControlStateDisabled = 1 << 1,
    };
    7衡便、Delegate
  • 用delegate做后綴献起,如<UIScrollViewDelegate>
  • 用optional修飾可以不實(shí)現(xiàn)的方法,用required修飾必須實(shí)現(xiàn)的方法
  • 當(dāng)你的委托的方法過(guò)多, 可以拆分?jǐn)?shù)據(jù)部分和其他邏輯部分, 數(shù)據(jù)部分用dataSource做后綴. 如<UITableViewDataSource>
  • 使用did和will通知Delegate已經(jīng)發(fā)生的變化或?qū)⒁l(fā)生的變化镣陕。
  • 類的實(shí)例必須為回調(diào)方法的參數(shù)之一
    1. 回調(diào)方法的參數(shù)只有類自己的情況谴餐,方法名要符合實(shí)際含義
    2. 回調(diào)方法存在兩個(gè)以上參數(shù)的情況,以類的名字開頭呆抑,以表明此方法是屬于哪個(gè)類的
      ==例:==
      @protocol UITableViewDataSource<NSObject>
      @required
      //回調(diào)方法存在兩個(gè)以上參數(shù)
  • (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
    @optional
    //回調(diào)方法的參數(shù)只有類自己
  • (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
@optional
//使用didwill通知Delegate

  • (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
    8岂嗓、方法
  • 方法名用小駝峰式命名
  • 方法名不要使用new作為前綴
  • 不要使用and來(lái)連接屬性參數(shù),如果方法描述兩種獨(dú)立的行為鹊碍,使用and來(lái)串接它們厌殉。
  • 方法實(shí)現(xiàn)時(shí)食绿,如果參數(shù)過(guò)長(zhǎng),則令每個(gè)參數(shù)占用一行公罕,以冒號(hào)對(duì)齊器紧。
  • 一般方法不使用前綴命名,私有方法可以使用統(tǒng)一的前綴來(lái)分組和辨識(shí)
  • 方法名要與對(duì)應(yīng)的參數(shù)名保持高度一致
  • 表示對(duì)象行為的方法楼眷、執(zhí)行性的方法應(yīng)該以動(dòng)詞開頭
  • 返回性的方法應(yīng)該以返回的內(nèi)容開頭铲汪,但之前不要加get,除非是間接返回一個(gè)或多個(gè)值罐柳。
  • 可以使用情態(tài)動(dòng)詞(動(dòng)詞前面can掌腰、should、will等)進(jìn)一步說(shuō)明屬性意思张吉,但不要使用do或does,因?yàn)檫@些助動(dòng)詞沒什么實(shí)際意義齿梁。也不要在動(dòng)詞前使用副詞或形容詞修飾
    ==例:==
    //不要使用 and 來(lái)連接屬性參數(shù)
  • (int)runModalForDirectory:(NSString *)path file:(NSString *)name types:(NSArray *)fileTypes; //推薦
  • (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; //反對(duì)
    //表示對(duì)象行為的方法、執(zhí)行性的方法
  • (void)insertModel:(id)model atIndex:(NSUInteger)atIndex;
  • (void)selectTabViewItem:(NSTableViewItem *)tableViewItem
    //返回性的方法
  • (instancetype)arrayWithArray:(NSArray *)array;
    //參數(shù)過(guò)長(zhǎng)的情況
  • (void)longMethodWith:(NSString *)theFoo
    rect:(CGRect)theRect
    interval:(CGFloat)theInterval
    {
    //Implementation
    }
    //不要加get
  • (NSSize) cellSize; //推薦
  • (NSSize) getCellSize; //反對(duì)
    //使用情態(tài)動(dòng)詞,不要使用do或does
  • (BOOL)canHide; //推薦
  • (BOOL)shouldCloseDocument; //推薦
  • (BOOL)doesAcceptGlyphInfo; //反對(duì)
    二芦拿、代碼注釋規(guī)范
    優(yōu)秀的代碼大部分是可以自描述的士飒,我們完全可以用代碼本身來(lái)表達(dá)它到底在干什么查邢,而不需要注釋的輔助蔗崎。
    但并不是說(shuō)一定不能寫注釋,有以下三種情況比較適合寫注釋:
  • 公共接口(注釋要告訴閱讀代碼的人扰藕,當(dāng)前類能實(shí)現(xiàn)什么功能)缓苛。
  • 涉及到比較深層專業(yè)知識(shí)的代碼(注釋要體現(xiàn)出實(shí)現(xiàn)原理和思想)。
  • 容易產(chǎn)生歧義的代碼(但是嚴(yán)格來(lái)說(shuō)邓深,容易讓人產(chǎn)生歧義的代碼是不允許存在的)未桥。
    除了上述這三種情況,如果別人只能依靠注釋才能讀懂你的代碼的時(shí)候芥备,就要反思代碼出現(xiàn)了什么問(wèn)題冬耿。
    最后,對(duì)于注釋的內(nèi)容萌壳,相對(duì)于“做了什么”亦镶,更應(yīng)該說(shuō)明“為什么這么做”。
    1袱瓮、import注釋
    如果有一個(gè)以上的import語(yǔ)句缤骨,就對(duì)這些語(yǔ)句進(jìn)行分組,每個(gè)分組的注釋是可選的尺借。
    // Frameworks

import <QuartzCore>;

// Models

import "NYTUser.h"

// Views

import "NYTButton.h"

import "NYTUserView.h"

2绊起、屬性注釋
寫在屬性之后,用兩個(gè)空格隔開
==例:==
@property (nonatomic, readwrite, strong) UIView *headerView; //注釋
3燎斩、方法聲明注釋:
一個(gè)函數(shù)(方法)必須有一個(gè)字符串文檔來(lái)解釋虱歪,除非它:

  • 非公開蜂绎,私有函數(shù)。
  • 很短笋鄙。
  • 顯而易見荡碾。
    而其余的,包括公開接口局装,重要的方法坛吁,分類,以及協(xié)議铐尚,都應(yīng)該伴隨文檔(注釋):
  • 以/開始
  • 第二行是總結(jié)性的語(yǔ)句
  • 第三行永遠(yuǎn)是空行
  • 在與第二行開頭對(duì)齊的位置寫剩下的注釋拨脉。
    建議這樣寫:
    /This comment serves to demonstrate the format of a doc string.
    Note that the summary line is always at most one line long, and after the opening block comment,
    and each line of text is preceded by a single space.
    /
    方法的注釋使用Xcode自帶注釋快捷鍵:Commond+option+/
    ==例:==
    /
    *
    <#Description#>
    @param tableView <#tableView description#>
    @param section <#section description#>
    @return <#return value description#>
    */
  • (CGFloat)tableView:(UITableView )tableView heightForHeaderInSection:(NSInteger)section
    {
    //...
    }
    4、代碼塊注釋
    單行的用//+空格開頭宣增,多行的采用/
    */注釋
    5玫膀、TODO
    使用//TODO:說(shuō)明 標(biāo)記一些未完成的或完成的不盡如人意的地方
    ==例:==
  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions
    {
    //TODO:增加初始化
    return YES;
    }
    三、代碼格式化規(guī)范
    1爹脾、指針
    位置
    定義一個(gè)對(duì)象時(shí)帖旨,指針
    靠近變量
    ==例:== NSString *userName;
    2、方法的聲明和定義
    在 - 灵妨、+和 返回值之間留一個(gè)空格解阅,方法名和第一個(gè)參數(shù)之間不留空格
    ==例:==
  • (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
    3、代碼縮進(jìn)
  • 不要在工程里使用 Tab 鍵泌霍,使用空格來(lái)進(jìn)行縮進(jìn)货抄。在 Xcode > Preferences > Text Editing 將 Tab 和自動(dòng)縮進(jìn)都設(shè)置為 4 個(gè)空格
  • Method與Method之間空一行
  • 一元運(yùn)算符與變量之間沒有空格、二元運(yùn)算符與變量之間必須有空格
    ==例:==
    !bValue
    fLength = fWidth * 2;
  • (void)sampleMethod1;
  • (void)sampleMethod2;
    4朱转、對(duì)method進(jìn)行分組
    使用#pragma mark -對(duì)method進(jìn)行分組

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 - Intial 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 - Lazy Loads

pragma mark - NSCopying

pragma mark - NSObject Methods

5蟹地、大括號(hào)寫法

  • 對(duì)于類的method:左括號(hào)另起一行寫(遵循蘋果官方文檔)
  • 對(duì)于其他使用場(chǎng)景(if,for,while,switch等): 左括號(hào)跟在第一行后邊
    ==例:==
  • (void)sampleMethod
    {
    BOOL someCondition = YES;
    if(someCondition) {
    // do something here
    }
    }
    6、property變量
    ==例:==
    @property (nonatomic, readwrite, strong) UIView *headerView; //注釋
    四藤为、編碼規(guī)范
    1怪与、if語(yǔ)句
    ①、須列出所有分支(窮舉所有的情況)缅疟,而且每個(gè)分支都須給出明確的結(jié)果分别。
    ==推薦這樣寫:==
    var hintStr;
    if (count < 3) {
    hintStr = "Good";
    } else {
    hintStr = "";
    }
    ==不推薦這樣寫:==
    var hintStr;
    if (count < 3) {
    hintStr = "Good";
    }
    ②、不要使用過(guò)多的分支窿吩,要善于使用return來(lái)提前返回錯(cuò)誤的情況茎杂,把最正確的情況放到最后返回。
    ==推薦這樣寫:==
    if (!user.UserName) return NO;
    if (!user.Password) return NO;
    if (!user.Email) return NO;
    return YES;
    ==不推薦這樣寫:==
    BOOL isValid = NO;
    if (user.UserName)
    {
    if (user.Password)
    {
    if (user.Email) isValid = YES;
    }
    }
    return isValid;
    ③纫雁、條件過(guò)多煌往,過(guò)長(zhǎng)的時(shí)候應(yīng)該換行。條件表達(dá)式如果很長(zhǎng),則需要將他們提取出來(lái)賦給一個(gè)BOOL值刽脖,或者抽取出一個(gè)方法
    ==推薦這樣寫:==
    if (condition1 &&
    condition2 &&
    condition3 &&
    condition4) {
    // Do something
    }

BOOL finalCondition = condition1 && condition2 && condition3 && condition4
if (finalCondition) {
// Do something
}

if ([self canDelete]){
// Do something
}

  • (BOOL)canDelete
    {
    BOOL finalCondition1 = condition1 && condition2
    BOOL finalCondition2 = condition3 && condition4
    return condition1 && condition2;
    }
    ==不推薦這樣寫:==
    if (condition1 && condition2 && condition3 && condition4) {
    // Do something
    }
    ④羞海、條件語(yǔ)句的判斷應(yīng)該是變量在右,常量在左曲管。
    ==推薦:==
    if (6 == count) {
    }
    if (nil == object) {
    }
    if (!object) {
    }
    ==不推薦:==
    if (count == 6) {
    }
    if (object == nil) {
    }
    if (object == nil)容易誤寫成賦值語(yǔ)句,if (!object)寫法很簡(jiǎn)潔
    ⑤却邓、每個(gè)分支的實(shí)現(xiàn)代碼都須被大括號(hào)包圍
    ==推薦:==
    if (!error) {
    return success;
    }
    ==不推薦:==
    if (!error)
    return success;
    可以如下這樣寫:
    if (!error) return success;
    2、for語(yǔ)句
    ①院水、不可在for循環(huán)內(nèi)修改循環(huán)變量腊徙,防止for循環(huán)失去控制。

for (int index = 0; index < 10; index++){
...
logicToChange(index)
}
②檬某、避免使用continue和break撬腾。
continue和break所描述的是“什么時(shí)候不做什么”,所以為了讀懂二者所在的代碼恢恼,我們需要在頭腦里將他們?nèi)》础?br> 其實(shí)最好不要讓這兩個(gè)東西出現(xiàn)民傻,因?yàn)槲覀兊拇a只要體現(xiàn)出“什么時(shí)候做什么”就好了,而且通過(guò)適當(dāng)?shù)姆椒ǔ“撸强梢詫⑦@兩個(gè)東西消滅掉的:

  • 如果出現(xiàn)了continue漓踢,只需要把continue的條件取反即可
    var filteredProducts = Array<String>()
    for level in products {
    if level.hasPrefix("bad") {
    continue
    }
    filteredProducts.append(level)
    }
    我們可以看到,通過(guò)判斷字符串里是否含有“bad”這個(gè)prefix來(lái)過(guò)濾掉一些值漏隐。其實(shí)我們是可以通過(guò)取反喧半,來(lái)避免使用continue的:
    for level in products {
    if !level.hasPrefix("bad") {
    filteredProducts.append(level)
    }
    }
  • 消除while里的break:將break的條件取反,并合并到主循環(huán)里
    在while里的break其實(shí)就相當(dāng)于“不存在”锁保,既然是不存在的東西就完全可以在最開始的條件語(yǔ)句中將其排除薯酝。
    while里的break:
    while (condition1) {
    ...
    if (condition2) {
    break;
    }
    }
    取反并合并到主條件:
    while (condition1 && !condition2) {
    ...
    }
  • 在有返回值的方法里消除break:將break轉(zhuǎn)換為return立即返回
    有人喜歡這樣做:在有返回值的方法里break之后半沽,再返回某個(gè)值爽柒。其實(shí)完全可以在break的那一行直接返回。
    func hasBadProductIn(products: Array<String>) -> Bool {
    var result = false
    for level in products {
    if level.hasPrefix("bad") {
    result = true
    break
    }
    }
    return result
    }
    遇到錯(cuò)誤條件直接返回:
    func hasBadProductIn(products: Array<String>) -> Bool {
    for level in products {
    if level.hasPrefix("bad") {
    return true
    }
    }
    return false
    }
    這樣寫的話不用特意聲明一個(gè)變量來(lái)特意保存需要返回的值者填,看起來(lái)非常簡(jiǎn)潔浩村,可讀性高。
    3占哟、Switch語(yǔ)句
    ①心墅、每個(gè)分支都必須用大括號(hào)括起來(lái)
    推薦這樣寫:
    switch (integer) {
    case 1: {
    // ...
    }
    break;
    case 2: {
    // ...
    break;
    }
    default:{
    // ...
    break;
    }
    }

②、使用枚舉類型時(shí)榨乎,不能有default分支怎燥, 除了使用枚舉類型以外,都必須有default分支

RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;
switch (menuType) {
case RWTLeftMenuTopItemMain: {
// ...
break;
}
case RWTLeftMenuTopItemShows: {
// ...
break;
}
case RWTLeftMenuTopItemSchedule: {
// ...
break;
}
}
在Switch語(yǔ)句使用枚舉類型的時(shí)候蜜暑,如果使用了default分支铐姚,在將來(lái)就無(wú)法通過(guò)編譯器來(lái)檢查新增的枚舉類型了。
4肛捍、函數(shù)
①隐绵、一個(gè)函數(shù)只做一件事(單一原則)
每個(gè)函數(shù)的職責(zé)都應(yīng)該劃分的很明確(就像類一樣)之众。
==推薦:==
dataConfiguration()
viewConfiguration()
==不推薦:==
void dataConfiguration()
{
...
viewConfiguration()
}
②、對(duì)于有返回值的函數(shù)(方法)依许,每一個(gè)分支都必須有返回值
==推薦:==
int function()
{
if(condition1){
return count1
}else if(condition2){
return count2
}else{
return defaultCount
}
}
==不推薦:==
int function()
{
if(condition1){
return count1
}else if(condition2){
return count2
}
}
③棺禾、對(duì)輸入?yún)?shù)的正確性和有效性進(jìn)行檢查,參數(shù)錯(cuò)誤立即返回
==推薦:==
void function(param1,param2)
{
if(param1 is unavailable){
return;
}
if(param2 is unavailable){
return;
}
//Do some right thing
}
④峭跳、如果在不同的函數(shù)內(nèi)部有相同的功能膘婶,應(yīng)該把相同的功能抽取出來(lái)單獨(dú)作為另一個(gè)函數(shù)
原來(lái)的調(diào)用:
void logic() {
a();
b();
if (logic1 condition) {
c();
} else {
d();
}
}
將a蛀醉,b函數(shù)抽取出來(lái)作為單獨(dú)的函數(shù)
void basicConfig() {
a();
b();
}
void logic1() {
basicConfig();
c();
}
void logic2() {
basicConfig();
d();
}
⑤竣付、將函數(shù)內(nèi)部比較復(fù)雜的邏輯提取出來(lái)作為單獨(dú)的函數(shù)
一個(gè)函數(shù)內(nèi)的不清晰(邏輯判斷比較多,行數(shù)較多)的那片代碼滞欠,往往可以被提取出去古胆,構(gòu)成一個(gè)新的函數(shù),然后在原來(lái)的地方調(diào)用它這樣你就可以使用有意義的函數(shù)名來(lái)代替注釋筛璧,增加程序的可讀性逸绎。
舉一個(gè)發(fā)送郵件的例子:
openEmailSite();
login();
writeTitle(title);
writeContent(content);
writeReceiver(receiver);
addAttachment(attachment);
send();
中間的部分稍微長(zhǎng)一些,我們可以將它們提取出來(lái):
void writeEmail(title, content,receiver,attachment)
{
writeTitle(title);
writeContent(content);
writeReceiver(receiver);
addAttachment(attachment);
}
然后再看一下原來(lái)的代碼:
openEmailSite();
login();
writeEmail(title, content,receiver,attachment)
send();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夭谤,一起剝皮案震驚了整個(gè)濱河市棺牧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌朗儒,老刑警劉巖颊乘,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異醉锄,居然都是意外死亡乏悄,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門恳不,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)檩小,“玉大人,你說(shuō)我怎么就攤上這事烟勋」媲螅” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵卵惦,是天一觀的道長(zhǎng)阻肿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)沮尿,這世上最難降的妖魔是什么丛塌? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上姨伤,老公的妹妹穿的比我還像新娘哨坪。我一直安慰自己,他們只是感情好乍楚,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布当编。 她就那樣靜靜地躺著,像睡著了一般徒溪。 火紅的嫁衣襯著肌膚如雪忿偷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天臊泌,我揣著相機(jī)與錄音鲤桥,去河邊找鬼。 笑死渠概,一個(gè)胖子當(dāng)著我的面吹牛茶凳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播播揪,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼贮喧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了猪狈?” 一聲冷哼從身側(cè)響起箱沦,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雇庙,沒想到半個(gè)月后谓形,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疆前,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年寒跳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峡继。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冯袍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碾牌,到底是詐尸還是另有隱情,我是刑警寧澤儡循,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布舶吗,位于F島的核電站,受9級(jí)特大地震影響择膝,放射性物質(zhì)發(fā)生泄漏誓琼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腹侣。 院中可真熱鬧叔收,春花似錦、人聲如沸傲隶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)跺株。三九已至复濒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乒省,已是汗流浹背巧颈。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留袖扛,地道東北人砸泛。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蛆封,于是被迫代替她去往敵國(guó)和親晾嘶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361