內(nèi)存管理/run time機制

Tables Are PS
1 基本原理
1.1 為什么要進行內(nèi)存管理
1.2 對象的基本結(jié)構(gòu)
1.3 引用計數(shù)器的作用
1.4 操作
1.5 對象的銷毀
2 相關(guān)概念和使用注意
3 內(nèi)存管理原則
3.1 原則
3.2 多對象管理
4 內(nèi)存管理代碼規(guī)范
4.1 基本數(shù)據(jù)類型
4.2 內(nèi)存管理代碼規(guī)范
4.2 dealloc方法的代碼規(guī)范
5 @property的參數(shù)
5.1 內(nèi)存管理相關(guān)參數(shù)
5.2 set和get方法的名稱
6 內(nèi)存管理中的循環(huán)引用問題以及解決
7 Autorelease
7.1 基本用法
7.2 好處
7.3 錯誤寫法
7.4 自動釋放池
7.5 使用注意
8 ARC內(nèi)存管理機制
8.1 ARC的判斷準則
8.2 指針分類
8.3 ARC的特點總結(jié)
8.4 NSString的retainCount
8.4 補充
9 runtime 機制
9.1 run time 相關(guān)原理
9.2 runtime 的相關(guān)實現(xiàn)

內(nèi)存分配
instruments 里面的leaks和allocation

OC 內(nèi)存管理

1.基本原理

1.1 為什么要進行內(nèi)存管理

由于移動設(shè)備的內(nèi)存極其有限筷凤,所以每個APP所占的內(nèi)存也是有限制的刻剥,當app所占用的內(nèi)存較多時,系統(tǒng)就會發(fā)出內(nèi)存警告臣嚣,這時需要回收一些不需要再繼續(xù)使用的內(nèi)存空間,比如回收一些不再使用的對象和變量等洁墙。
下列行為都會增加一個app的內(nèi)存占用

  • 創(chuàng)建一個OC對象
  • 定義一個變量
  • 調(diào)用一個函數(shù)或者方法

管理范圍:任何繼承NSObject的對象剿配,對其他的基本數(shù)據(jù)類型無效。
本質(zhì)原因是因為對象和其他數(shù)據(jù)類型在系統(tǒng)中的存儲空間不一樣咽斧,其它局部變量主要存放于棧中堪置,而對象存儲于堆中,當代碼塊結(jié)束時這個代碼塊中涉及的所有局部變量會被回收张惹,指向?qū)ο蟮闹羔樢脖换厥?此時對象已經(jīng)沒有指針指向舀锨,要是依然存在于內(nèi)存中,會造成內(nèi)存泄露宛逗。

1.2 對象的基本結(jié)構(gòu)

每個OC對象都有自己的引用計數(shù)器坎匿,是一個整數(shù)表示對象被引用的次數(shù),即現(xiàn)在有多少東西在使用這個對象雷激。對象剛被創(chuàng)建時替蔬,默認計數(shù)器值為1,當計數(shù)器的值變?yōu)?時屎暇,則對象銷毀承桥。
在每個OC對象內(nèi)部,都專門有4個字節(jié)的存儲空間來存儲引用計數(shù)器根悼。

1.3 引用計數(shù)器的作用

判斷對象要不要回收的唯一依據(jù)就是計數(shù)器是否為0凶异,若不為0則存在。為0則調(diào)用dealloc函數(shù)挤巡。

1.4 操作

給對象發(fā)送消息剩彬,進行相應的計數(shù)器操作。
Retain消息:使計數(shù)器+1,改方法返回對象本身
Release消息:使計數(shù)器-1(并不代表釋放對象)
retainCount消息:獲得對象當前的引用計數(shù)器值

1.5 對象的銷毀

當一個對象的引用計數(shù)器為0時,那么它將被銷毀驮瞧,其占用的內(nèi)存被系統(tǒng)回收叹括。
當對象被銷毀時,系統(tǒng)會自動向?qū)ο蟀l(fā)送一條dealloc消息绍坝,一般會重寫dealloc方法徘意,在這里釋放相關(guān)的資源,dealloc就像是對象的“臨終遺言”轩褐。一旦重寫了dealloc方法就必須調(diào)用[super dealloc]椎咧,并且放在代碼塊的最后調(diào)用(不能直接調(diào)用dealloc方法)。
一旦對象被回收了,那么他所占據(jù)的存儲空間就不再可用勤讽,堅持使用會導致程序崩潰(野指針錯誤)蟋座。

2.相關(guān)概念和使用注意

野指針錯誤:訪問了一塊壞的內(nèi)存(已經(jīng)被回收的,不可用的內(nèi)存)脚牍。
僵尸對象:所占內(nèi)存已經(jīng)被回收的對象向臀,僵尸對象不能再被使用。(打開僵尸對象檢測)



空指針:沒有指向任何東西的指針(存儲的東西是0,null诸狭,nil)券膀,給空指針發(fā)送消息不會報錯
注意:不能使用[p retaion]讓僵尸對象起死復生。

3.內(nèi)存管理原則

3.1原則

只要還有人在使用某個對象驯遇,那么這個對象就不會被回收芹彬;
只要你想使用這個對象,那么就應該讓這個對象的引用計數(shù)器+1叉庐;
當你不想使用這個對象時舒帮,應該讓對象的引用計數(shù)器-1;

  • 誰創(chuàng)建陡叠,誰release
    如果你通過alloc,new,copy來創(chuàng)建了一個對象会前,那么你就必須調(diào)用release或者autorelease方法
    不是你創(chuàng)建的就不用你去負責
  • 誰retain,誰release**
    只要你調(diào)用了retain匾竿,無論這個對象時如何生成的瓦宜,你都要調(diào)用release
  • 總結(jié)
    有始有終,有加就應該有減岭妖。曾經(jīng)讓某個對象計數(shù)器加1临庇,就應該讓其在最后-1.

3.2 多對象管理

單個對象的內(nèi)存管理, 看起來非常簡單。如果對多個對象進行內(nèi)存管理, 并且對象之間是有聯(lián)系的, 那么管理就會變得比較復雜

其實, 多個對象的管理思路 跟 很多游戲的房間管理差不多
比如斗地主 \ QQ堂

有一個房間昵慌,有人要用假夺,一號使用retaincount+1 ,release下斋攀,二號使用同理已卷。當沒人使用的話,釋放房間
總的來說, 有這么幾點管理規(guī)律

只要還有人在用某個對象淳蔼,那么這個對象就不會被回收
只要你想用這個對象侧蘸,就讓對象的計數(shù)器+1
當你不再使用這個對象時,就讓對象的計數(shù)器-1

4.內(nèi)存管理代碼規(guī)范

只要調(diào)用了alloc鹉梨,就必須有release(autorelease)

4.1 基本數(shù)據(jù)類型:直接復制

-(void)setAge:(int)age
{
_age=age;
}

4.2 OC對象類型

-(void)setCar:(Car *)car
{
//1.先判斷是不是新傳進來的對象
If(car!=_car)
{
//2 對舊對象做一次release
[_car release];//若沒有舊對象讳癌,則沒有影響
//3.對新對象做一次retain
_car=[car retain];
}
}

4.3 dealloc方法的代碼規(guī)范

  • 一定要[super dealloc],而且要放到最后
  • 對self(當前)所擁有的的其他對象做一次release操作
-(void)dealloc
{
[_car release];
[super dealloc];
}

下面代碼都會引發(fā)內(nèi)存泄露

p.dog = [[Dog alloc] init];

[[Dog alloc] init].weight = 20.8;

5. @property的參數(shù)

5.1內(nèi)存管理相關(guān)參數(shù)

Retain:對對象release舊值存皂,retain新值(適用于OC對象類型)完整的set方法晌坤,管理內(nèi)存的參數(shù)
Assign:直接賦值(默認,不寫參數(shù)的都是assign,適用于非oc對象類型骤菠,這樣對位于棧的系統(tǒng)自動生成的變量)
Copy:release舊值它改,copy新值,用于NSString\block等類型

ARC中的@property
strong : 用于OC對象, 相當于MRC中的retain
weak : 用于OC對象, 相當于MRC中的assign
assign : 用于基本數(shù)據(jù)類型, 跟MRC中的assign一樣
copy : 一般用于NSString, 跟MRC中的copy一樣

是否要生成set方法(若為只讀屬性,則不生成)
Readonly:只讀商乎,只會生成getter的聲明和實現(xiàn)
Readwrite:默認的搔课,同時生成setter和getter的聲明和實現(xiàn)

多線程管理(蘋果在一定程度上屏蔽了多線程操作)
Nonatomic:高性能,一般使用這個
Atomic:低性能

5.2 Set和get方法的名稱

修改set和get方法的名稱截亦,主要用于布爾類型爬泥。因為返回布爾類型的方法名一般以is開頭,修改名稱一般用在布爾類型中的getter崩瓤。
@propery(setter=setAbc,getter=isRich) BOOL rich;
BOOL b=p.isRich;// 調(diào)用

6. 內(nèi)存管理中的循環(huán)引用問題以及解決

案例:每個人有一張身份證袍啡,每張身份證對應一個人,不能使用#import的方式相互包含却桶,這就形成了循環(huán)引用境输。
新的關(guān)鍵字:
@class 類名;——解決循環(huán)引用問題颖系,提高性能嗅剖;
@class僅僅告訴編譯器,在進行編譯的時候把后面的名字作為一個類來處理嘁扼。
@class的作用:聲明一個類信粮,告訴編譯器某個名稱是一個類

那么我們怎么使用@class,

  1. 在.h文件中使用@class來聲明類
  2. 在.m文件中真正要使用到的時候趁啸,使用#import來包含類中的所有東西

兩端循環(huán)引用的解決方法

循環(huán)retain的場景
比如A對象retain了B對象强缘,B對象retain了A對象

循環(huán)retain的弊端
這樣會導致A對象和B對象永遠無法釋放

循環(huán)retain的解決方案
當兩端互相引用時,應該一端用retain不傅、一端用assign(使用assign的在dealloc中也不用再release)

7 Autorelease

7.1 基本用法

  1. 會將對象放到一個自動釋放池中
  2. 當自動釋放池被銷毀時旅掂,會對池子里的所有對象做一次release
  3. 會返回對象本身
  4. 調(diào)用完autorelease方法后,對象的計數(shù)器不受影響(銷毀時影響)

7.2 好處

  • 不需要再關(guān)心對象釋放的時間
  • 不需要再關(guān)心什么時候調(diào)用release

7.3 錯誤寫法

連續(xù)調(diào)用多次autorelease访娶,釋放池銷毀時執(zhí)行兩次release(-1嗎商虐?)

Alloc之后調(diào)用了autorelease,之后又調(diào)用了release崖疤。

7.4 自動釋放池

在ios程序運行過程中秘车,會創(chuàng)建無數(shù)個池子,這些池子都是以棧結(jié)構(gòu)(先進后出)存在的戳晌。
當一個對象調(diào)用autorelease時鲫尊,會將這個對象放到位于棧頂?shù)尼尫懦刂?/p>

7.5 Autorelease注意

  1. 系統(tǒng)自帶的方法中痴柔,如果不包含alloc new copy等沦偎,則這些方法返回的對象都是autorelease的,如[NSDate date];
  2. 開發(fā)中經(jīng)常會寫一些類方法來快速創(chuàng)建一個autorelease對象豪嚎,創(chuàng)建對象時不要直接使用類名搔驼,而是使用self
  3. 占用內(nèi)存較大的對象,不要隨便使用autorelease侈询,應該使用release來精確控制;而占用內(nèi)存較小的對象使用autorelease舌涨,沒有太大的影響

8. ARC內(nèi)存管理機制

8.1 ARC的判斷準則

只要沒有強指針指向?qū)ο螅瑢ο缶蜁会尫拧?/p>

8.2 指針分類

  • 強指針:默認的情況下扔字,所有的指針都是強指針囊嘉,關(guān)鍵字strong
  • 弱指針:___weak關(guān)鍵字修飾的指針

聲明一個弱指針如下:___weak Person *p;
ARC中,只要弱指針指向的對象不在了革为,就直接把弱指針做清空操作扭粱。

___weak Person * p= [[Person alloc] init];

不合理,對象一創(chuàng)建出來就被釋放掉震檩,對象釋放掉后琢蛤,ARC把指針自動清零。
ARC中在property處不再使用retain,而是使用strong抛虏,在dealloc中不需要再[super dealloc]博其。
@property(nonatomic,strong)Dog *dog;// 意味著生成的成員變量_dog是一個強指針,相當于以前的retain迂猴。

如果換成是弱指針慕淡,則換成weak,不需要加 ____ 沸毁。

8.3 ARC的特點總結(jié)

  1. 不允許調(diào)用release儡率,retain,retainCount
  2. 允許重寫dealloc,但是不允許調(diào)用[super dealloc]
  3. @property的參數(shù):
    Strong:相當于原來的retain(適用于OC對象類型)以清,成員變量是強指針
    Weak:相當于原來的assign,(適用于oc對象類型)儿普,成員變量是弱指針
    Assign:適用于非OC對象類型(基礎(chǔ)類型)

8.4 NSString的retainCount

** 提示:字符串是特殊的對象,但不需要使用release手動釋放掷倔,這種字符串對象默認就是autorelease的眉孩,不用額外的去管內(nèi)存,存放到堆中勒葱。 **

//1. 字符串常量
NSString *str1 = @"string";
NSLog(@"str1: %ld",[str1 retainCount]); // -1或18446744073709551615(即UINT_MAX ( Maximum value an `unsigned int'))

//因為"str"為字符串常量浪汪,系統(tǒng)不會收回,也不會對其作引用計數(shù)凛虽,即使我們對str如何retain或release死遭。就是為-1.
 
//2. stringWithFormat
NSString *str2 = [NSString stringWithFormat:@"%s", "test"];
NSLog(@"str2:%ld",[str2 retainCount]); // 1
//使用stringWithFormat創(chuàng)建的NSString為變量,系統(tǒng)會進行引用計數(shù)凯旋。  以前為1呀潭,現(xiàn)在為-1.
 
//3. stringWithString
stringWithString這個方法比較特別:它的retainCount取決于它后面跟的string對象

NSString *str3 = [NSString stringWithString:@"test"];
NSString *str4 = [NSString stringWithString:[NSString stringWithFormat:@"test,%d  ,%d",1,3]];
NSLog(@"str3:%ld",[str3 retainCount]); // -1
NSLog(@"str4:%ld",[str4 retainCount]); // 2
//可以看到第一個為"常量"對象钉迷,其retainCount方法的實現(xiàn)返回的是maxIntValue。
//第二個為2钠署,這個方法生成的只是一個對另一個對象的引用糠聪。一個對象實例,兩次的stringWithString谐鼎,它的retainCount為2舰蟆,同時都被當前的AutoreleasePool管理。

8.5 補充

** 讓程序兼容ARC和非ARC部分狸棍。轉(zhuǎn)變?yōu)榉茿RC -fno-objc-arc 轉(zhuǎn)變?yōu)锳RC的身害, -f-objc-arc 。**
ARC也需要考慮循環(huán)引用問題:一端使用retain草戈,另一端使用assign题造。


set  
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];
        Car *car = [Car new];
        car.speed = 100;
        [p setCar:car];
        [p drive];
        
        [car release];
        
        /*
        //重復調(diào)用,已經(jīng)釋放了猾瘸,要改加上if語句去進行判斷
        [p setCar:car];
        [p drive];
        */
        
        Car *car2 = [Car new];
        car2.speed = 200;
        [p setCar:car2];
        
        
        [p drive];
        [car2 release];
        [p  release];


    }
    return 0;
}  

#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
{
    Car *_car;
    NSString *_name;
}

- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setCar:(Car *)car;
- (Car *)car;
- (void)drive;
@end  

#import "Person.h"

@implementation Person
- (void)dealloc{
    //目的是要保證在p對象存在的時候界赔,car對象一定存在
    //對象p被銷毀的時候
    [_car release];
    [_name release];
    [super dealloc];
    NSLog(@"被釋放了");
}

- (void)setName:(NSString *)name{
    if (_name != name) {
        [_name release];
        _name = [name retain];
    }

}
- (NSString *)name
{
    return _name;
}


- (void)setCar:(Car *)car{
    //第一次是空,所以release無所謂牵触,第二次減一淮悼,要是不release的話,會造成內(nèi)存泄露的問題揽思。
    //car retainCount= 1
    if (_car != car) {
    [car release];
    }
   
    //car2 2
    _car = [car retain];//引用計數(shù)加1 袜腥,返回self
}
- (void)drive{
    [_car run];
}
@end  

#import <Foundation/Foundation.h>

@interface Car : NSObject
@property int speed;

- (void)run;
@end  

#import "Car.h"

@implementation Car
- (void)dealloc{
    [super dealloc];
    NSLog(@"被釋放了  %d",_speed);
}
- (void)run{
    NSLog(@"I can run");
}
@end

9. runtime 機制

9.1 run time 相關(guān)原理

對于runtime機制,在網(wǎng)上找到的資料大概就是怎么去用這些東西钉汗,以及查看runtime.h頭文件中的實現(xiàn)羹令,當然這確實是一種很好的學習方法,但是损痰,其實我們還是不會知道runtime底層編譯成C++語言之后做了什么福侈? 查到一個大牛給資料,頓時對runtime有了一定認識卢未!

我們隨便寫一個小程序肪凛,代碼如下: person類頭文件如下,

<!-- lang: cpp -->
#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic, strong) NSString *name; 
@property (nonatomic, assign) int age;

@end

main.m文件如下
<!-- lang: cpp -->
int main(int argc, const char * argv[])

{
Person *p = [[Person alloc] init];
NSString *str = @"zhangsan";
p.name = str;
// p.name 等價于
[p setName:str];
p.age = 20;
return 0;

}

然后我們打開終端辽社,在命令行找到cd到文件目錄伟墙,然后中輸入:
clang -rewrite-objc main.m

命令可以將main.m編譯成C++的代碼,改成不同的文件名滴铅,就會生成不同的c++代碼 這是就生成了main.cpp這個c++文件戳葵,打開文件代碼 查看該main.cpp最底下的main函數(shù), 這樣我們就可以看到底層具體實現(xiàn)的方式汉匙!
這時拱烁,我們就需要知道這些方法:
**
objc_msgSend 可以給對象發(fā)送消息
objc_getClass(“Person”) 可以獲取到指定名稱的對象
sel_registerName(“alloc”) 可以調(diào)用到對象的方法
**

通過查看生蚁,c++代碼,我們得出結(jié)論:
使用objc_msgSend函數(shù)邻梆,給objc_getClass函數(shù)實例化的對象發(fā)送sel_registerName獲取到的方法 這么一個消息 代碼是給人看的守伸,順帶讓機器實現(xiàn)功能绎秒。
日常的程序開發(fā)過程中浦妄,要少用runtime,
那什么時候會使用runtime呢见芹? runtime應用的時機:
1> 當需要非常高的性能開發(fā)時剂娄,使用runtime,注釋:oc的代碼已經(jīng)無法滿足性能需求
2> 當我們對系統(tǒng)內(nèi)部的實現(xiàn)很好奇的時候玄呛,可以用clang反編譯成c++去看底層的實現(xiàn)機制阅懦!

項目講解的是runtime的底層實現(xiàn)原理, 如果想要知道runtime是怎么用的徘铝,可以查看runtime.h頭文件查看耳胎! 以下是runtime機制方法的一些使用方法介紹,希望對大家有用惕它!
相關(guān)技術(shù)文檔:
http://www.tuicool.com/articles/uimInm http://blog.csdn.net/lengshengren/article/details/17764135

9.2runtime 的相關(guān)實現(xiàn)

首先怕午,第一個問題,

  1. runtime實現(xiàn)的機制是什么?

runtime是一套比較底層的純C語言API, 屬于1個C語言庫, 包含了很多底層的C語言API淹魄。 在我們平時編寫的OC代碼中, 程序運行過程時, 其實最終都是轉(zhuǎn)成了runtime的C語言代碼, runtime算是OC的幕后工作者比如說郁惜,下面一個創(chuàng)建對象的方法中, 舉例: OC :

 [[MJPerson alloc] init] 
runtime : 
objc_msgSend(objc_msgSend(“MJPerson” , “alloc”), “init”)
  1. runtime 用來干什么呢甲锡?兆蕉?用在那些地方呢?怎么用呢缤沦?

runtime是屬于OC的底層, 可以進行一些非常底層的操作(用OC是無法現(xiàn)實的, 不好實現(xiàn))

  • 在程序運行過程中, 動態(tài)創(chuàng)建一個類(比如KVO的底層實現(xiàn))
  • 在程序運行過程中, 動態(tài)地為某個類添加屬性\方法, 修改屬性值\方法
  • 遍歷一個類的所有成員變量(屬性)\所有方法

例如:我們需要對一個類的屬性進行歸檔解檔的時候?qū)傩蕴貏e的多虎韵,這時候,我們就會寫很多對應的代碼缸废,但是如果使用了runtime就可以動態(tài)設(shè)置劝术!

例如,PYPerson.h的文件如下所示

import

@interface PYPerson : NSObject 
@property (nonatomic, assign) int age; 
@property (nonatomic, assign) int height;
@property (nonatomic, copy) NSString *name; 
@property (nonatomic, assign) int age2; 
@property (nonatomic, assign) int height2; 
@property (nonatomic, assign) int age3; 
@property (nonatomic, assign) int height3; 
@property (nonatomic, assign) int age4; 
@property (nonatomic, assign) int height4;
@end

而PYPerson.m實現(xiàn)文件的內(nèi)容如下


#import "PYPerson.h"

import
@implementation  PYPerson
- (void)encodeWithCoder:(NSCoder *)encoder {
 unsigned int count = 0; 
Ivar *ivars = class_copyIvarList([PYPerson class], &count);

for (int i = 0; i<count; i++) {

// 取出i位置對應的成員變量Ivar ivar = ivars[i];
// 查看成員變量const char *name = ivar_getName(ivar);
// 歸檔NSString *key = [NSString stringWithUTF8String:name];
id value = [self valueForKey:key];
[encoder encodeObject:value forKey:key];
}
free(ivars); 
}

(id)initWithCoder:(NSCoder *)decoder { 
if (self = [super init]) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([PYPerson class], &count);for (int i = 0; i<count; i++) { 
// 取出i位置對應的成員變量 Ivar ivar = ivars[i]; 
// 查看成員變量 const char *name = ivar_getName(ivar);
 // 歸檔 NSString *key = [NSString stringWithUTF8String:name]; id value = [decoder decodeObjectForKey:key]; 
// 設(shè)置到成員變量身上 [self setValue:value forKey:key];}free(ivars);

}
 return self; 
}

@end

這樣我們可以看到歸檔和解檔的案例其實是runtime寫下的.

學習runtime機制首先要了解下面幾個問題

  1. 相關(guān)的頭文件和函數(shù)
    利用頭文件呆奕,我們可以查看到runtime中的各個方法养晋!

  2. 相關(guān)應用
    NSCoding(歸檔和解檔, 利用runtime遍歷模型對象的所有屬性)
    字典 –> 模型 (利用runtime遍歷模型對象的所有屬性, 根據(jù)屬性名從字典中取出對應的值, 設(shè)置到模型的屬性上)
    KVO(利用runtime動態(tài)產(chǎn)生一個類)
    用于封裝框架(想怎么改就怎么改) 這就是我們runtime機制的只要運用方向

  3. 相關(guān)函數(shù)
    objc_msgSend : 給對象發(fā)送消息
    class_copyMethodList : 遍歷某個類所有的方法
    class_copyIvarList : 遍歷某個類所有的成員變量
    class_….. 這是我們學習runtime必須知道的函數(shù)!

  4. 必備常識 1> Ivar : 成員變量 2> Method : 成員方法 從上面例子中我們看到我們定義的成員變量梁钾,如果要是動態(tài)創(chuàng)建方法绳泉,可以使用Method.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市姆泻,隨后出現(xiàn)的幾起案子零酪,更是在濱河造成了極大的恐慌冒嫡,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件四苇,死亡現(xiàn)場離奇詭異孝凌,居然都是意外死亡,警方通過查閱死者的電腦和手機月腋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門蟀架,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人榆骚,你說我怎么就攤上這事片拍。” “怎么了妓肢?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵捌省,是天一觀的道長。 經(jīng)常有香客問我碉钠,道長纲缓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任喊废,我火速辦了婚禮祝高,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘操禀。我一直安慰自己褂策,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布颓屑。 她就那樣靜靜地躺著斤寂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪揪惦。 梳的紋絲不亂的頭發(fā)上遍搞,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音器腋,去河邊找鬼溪猿。 笑死,一個胖子當著我的面吹牛纫塌,可吹牛的內(nèi)容都是我干的诊县。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼措左,長吁一口氣:“原來是場噩夢啊……” “哼依痊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怎披,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤胸嘁,失蹤者是張志新(化名)和其女友劉穎瓶摆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體性宏,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡群井,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了毫胜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片书斜。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖指蚁,靈堂內(nèi)的尸體忽然破棺而出菩佑,到底是詐尸還是另有隱情自晰,我是刑警寧澤凝化,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站酬荞,受9級特大地震影響搓劫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜混巧,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一枪向、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咧党,春花似錦秘蛔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛙埂,卻和暖如春倦畅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绣的。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工叠赐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屡江。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓芭概,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惩嘉。 傳聞我的和親對象是個殘疾皇子罢洲,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

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