swift 進(jìn)階:內(nèi)存管理 & Runtime

swift 進(jìn)階之路:學(xué)習(xí)大綱

swift引用計(jì)數(shù):

  • swift對(duì)象都是以HeapObject為模板創(chuàng)建,其中HeapObject的模板中第二個(gè)元素檐盟,是refCount引用計(jì)數(shù)屬性传睹,該屬性記錄了strong(強(qiáng)引用計(jì)數(shù))和unowned(弱引用計(jì)數(shù))等信息叫潦。
  • weak修飾的對(duì)象,會(huì)另外生成WeakReference對(duì)象,內(nèi)部HeapObjectSideTableEntry散列表類- - 在原heapObject類的基礎(chǔ)上水援,重新記錄了refCount(管理strong和unowned引用計(jì)數(shù))并新增了weakBits弱引用計(jì)數(shù)

swift與OC強(qiáng)引用計(jì)數(shù)對(duì)比

  • OC中創(chuàng)建實(shí)例對(duì)象時(shí)為0

  • swift中創(chuàng)建實(shí)例對(duì)象時(shí)默認(rèn)為1

1. Swift三大引用計(jì)數(shù)(strong茅郎、unowned蜗元、weak)

  • 不管是哪種引用,持有的都是原對(duì)象(從p到p5內(nèi)存地址可以看出)
  • 在每一行執(zhí)行完后系冗,x/4g打印p對(duì)象內(nèi)存信息奕扣,在第二個(gè)地址上,可以清晰感受到掌敬,強(qiáng)引用無(wú)主引用的引用計(jì)數(shù)在有規(guī)律的增加惯豆,而弱引用卻沒有變化。

refCount內(nèi)存布局

  • isImmortal(0)

  • UnownedRefCount(1-31): unowned的引用計(jì)數(shù)

  • isDeinitingMask(32):是否進(jìn)行釋放操作

  • StrongExtraRefCount(33-62): 強(qiáng)引用計(jì)數(shù)

  • UseSlowRC(63)

重點(diǎn)關(guān)注UnownedRefCountStrongExtraRefCount

總結(jié)

對(duì)于HeapObject來(lái)說(shuō)奔害,其refCounts有兩種:

  • 無(wú)弱引用:strongCount+ unownedCount
  • 有弱引用:object + xxx + (strongCount + unownedCount) + weakCount
HeapObject {
    InlineRefCountBit {strong count + unowned count }

    HeapObjectSideTableEntry{
        HeapObject *object
        xxx
        strong Count + unowned Count(uint64_t)//64位
        weak count(uint32_t)//32位
    }
}

弱引用

  • 我們知道swift是使用ARC(自動(dòng)引用計(jì)數(shù)管理)的楷兽。如果產(chǎn)生循環(huán)引用,我們必須有弱引用機(jī)制去打破循環(huán)华临。

swift中的弱引用芯杀,使用weak修飾。與OC不同的是:

  • OC:
    弱引用計(jì)數(shù)是存放在全局維護(hù)散列表中雅潭,isa中會(huì)記錄是否使用了散列表揭厚。
    引用計(jì)數(shù)0時(shí),自動(dòng)觸發(fā)dealloc,會(huì)檢查清空當(dāng)前對(duì)象散列表計(jì)數(shù)寻馏。
  • swift:
    弱引用計(jì)數(shù)也是存放在散列表中棋弥,但這個(gè)散列表不是全局的。
*   如果對(duì)象`沒有`使用`weak`弱引用诚欠,就是單純的`HeapObject`對(duì)象顽染,`沒有散列表`漾岳。
*   如果使用`weak`弱引用,會(huì)變?yōu)閌WeakReference`對(duì)象粉寞。這是一個(gè)`Optionl(可空對(duì)象)`尼荆。其結(jié)構(gòu)中自帶`散列表計(jì)數(shù)`區(qū)域。
    但`swift`的`散列表`與`refCount`無(wú)關(guān)聯(lián)唧垦。當(dāng)`強(qiáng)引用計(jì)數(shù)`為`0`時(shí)捅儒,不會(huì)觸發(fā)`散列表`的清空。而是在`下次訪問(wèn)`發(fā)現(xiàn)`當(dāng)前對(duì)象不存在(為nil)`時(shí)振亮,會(huì)清空`散列表計(jì)數(shù)`巧还。

下面,我們通過(guò)案例源碼來(lái)分析swift弱引用WeakReference對(duì)象內(nèi)存結(jié)構(gòu)

案例:

  • 可以發(fā)現(xiàn):
    weak修飾前坊秸,p對(duì)象是HeapObject類型麸祷,可從refCount中看出強(qiáng)引用計(jì)數(shù)無(wú)主引用計(jì)數(shù)
    weak修飾后褒搔,p對(duì)象的類型變了
image
  • 可以看到weak修飾p1對(duì)象阶牍,變成了optinal可選值
    (不難理解星瘾,weak修飾對(duì)象走孽,會(huì)改變原對(duì)象的引用計(jì)數(shù),只是一層可空狀態(tài)
image
  • 斷點(diǎn)琳状,匯編可以看到swift_weakInit初始化磕瓷,swift_weakDestroy釋放。
image
  • 常規(guī)對(duì)象弱引用對(duì)象區(qū)別:
image

2. 內(nèi)存管理 - 循環(huán)引用

主要是研究閉包捕獲外部變量念逞,以下面代碼為例

var age = 10
let clourse = {
    age += 1
}
clourse()
print(age)

<!--打印結(jié)果-->
11

從輸出結(jié)果中可以看出:閉包內(nèi)部對(duì)變量的修改將會(huì)改變外部原始變量的值,主要原因是閉包會(huì)捕獲外部變量生宛,這個(gè)與OC中的block是一致的

  • 定義一個(gè)類,在test函數(shù)作用域消失后肮柜,會(huì)執(zhí)行init
class CJLTeacher {
    var age = 18
    //反初始化器(當(dāng)前實(shí)例對(duì)象即將被回收)
    deinit {
        print("CJLTeacher deinit")
    }
}
func test(){
    var t = CJLTeacher()
}
test()

<!--打印結(jié)果-->
CJLTeacher deinit

  • 修改例子陷舅,通過(guò)閉包修改其屬性值
class CJLTeacher {
    var age = 18
    //反初始化器(當(dāng)前實(shí)例對(duì)象即將被回收)
    deinit {
        print("CJLTeacher deinit")
    }
}
var t = CJLTeacher()
let clourse = {
    t.age += 1
}
clourse()

<!--打印結(jié)果-->
11

  • 【修改1】將上面例子修改為如下,其中閉包是否對(duì)t有強(qiáng)引用审洞?
class CJLTeacher {
    var age = 18
    deinit {
        print("CJLTeacher deinit")
    }
}

func test(){
    var t = CJLTeacher()
    let clourse = {
        t.age += 1
    }
    clourse()
}
test()

<!--運(yùn)行結(jié)果-->
CJLTeacher deinit

運(yùn)行結(jié)果發(fā)現(xiàn)莱睁,閉包對(duì) t 并沒有強(qiáng)引用

  • 【修改2】繼續(xù)修改例子為如下,是否有強(qiáng)引用芒澜?
class CJLTeacher {
    var age = 18

    var completionBlock: (() ->())?

    deinit {
        print("CJLTeacher deinit")
    }
}

func test(){
    var t = CJLTeacher()
    t.completionBlock = {
        t.age += 1
    }
}
test()

從運(yùn)行結(jié)果發(fā)現(xiàn)仰剿,沒有執(zhí)行deinit方法,即沒有打印CJLTeacher deinit痴晦,所以這里有循環(huán)引用

image

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

有兩種方式可以解決swift中的循環(huán)引用

  • 【方式一】使用weak修飾閉包傳入的參數(shù)南吮,其中參數(shù)的類型是optional
func test(){
    var t = CJLTeacher()
    t.completionBlock = { [weak t] in
        t?.age += 1
    } 
}

  • 【方式二】使用unowned修飾閉包參數(shù),與weak的區(qū)別在于unowned不允許被設(shè)置為nil誊酌,即總是假定有值
func test(){
    var t = CJLTeacher()
    t.completionBlock = { [unowned t] in
        t.age += 1
    } 
}

捕獲列表

  • [weak t] / [unowned t] 在swift中被稱為捕獲列表

  • 定義在參數(shù)列表之前

  • 【書寫方式】捕獲列表被寫成用逗號(hào)括起來(lái)的表達(dá)式列表部凑,并用方括號(hào)括起來(lái)

  • 如果使用捕獲列表露乏,則即使省略參數(shù)名稱、參數(shù)類型和返回類型涂邀,也必須使用in關(guān)鍵字

  • [weak t] 就是取t的弱引用對(duì)象 類似weakself

請(qǐng)問(wèn)下面代碼的clourse()調(diào)用后瘟仿,輸出的結(jié)果是什么?

func test(){
    var age = 0
    var height = 0.0
    //將變量age用來(lái)初始化捕獲列表中的常量age比勉,即將0給了閉包中的age(值拷貝)
    let clourse = {[age] in
        print(age)
        print(height)
    }
    age = 10
    height = 1.85
    clourse()
}

<!--打印結(jié)果-->
0
1.85

所以從結(jié)果中可以得出:對(duì)于捕獲列表中的每個(gè)常量劳较,閉包會(huì)利用周圍范圍內(nèi)具有相同名稱的常量/變量,來(lái)初始化捕獲列表中定義的常量浩聋。有以下幾點(diǎn)說(shuō)明:

  • 捕獲列表中的常量是值拷貝观蜗,而不是引用

  • 捕獲列表中的常量的相當(dāng)于復(fù)制了變量age的值

  • 捕獲列表中的常量是只讀的,即不可修改

3衣洁、 swift中Runtime探索

請(qǐng)問(wèn)下面代碼嫂便,會(huì)打印方法和屬性嗎?

class CJLTeacher {
    var age: Int = 18
    func teach(){
        print("teach")
    }
}

let t = CJLTeacher()

func test(){
    var methodCount: UInt32 = 0
    let methodList = class_copyMethodList(CJLTeacher.self, &methodCount)
    for i in 0..<numericCast(methodCount) {
        if let method = methodList?[I]{
            let methodName = method_getName(method)
            print("方法列表:\(methodName)")
        }else{
            print("not found method")
        }
    }

    var count: UInt32 = 0
    let proList = class_copyPropertyList(CJLTeacher.self, &count)
    for i in 0..<numericCast(count) {
        if let property = proList?[I]{
            let propertyName = property_getName(property)
            print("屬性成員屬性:\(property)")
        }else{
            print("沒有找到你要的屬性")
        }
    }
    print("test run")
}
test()

運(yùn)行結(jié)果如下闸与,發(fā)現(xiàn)并沒有打印方法和屬性

image
  • 【嘗試1】如果給屬性 和 方法 都加上 @objc,可以打印嗎岸售?

    image

    從運(yùn)行結(jié)果看践樱,是可以打印,但是由于類并沒有暴露給OC凸丸,所以O(shè)C是無(wú)法使用的拷邢,這樣做是沒有意義的

  • 【嘗試2】如果swift的類繼承NSObject,沒有@objc修飾屬性和方法屎慢,是否可以打印全部屬性+方法瞭稼?

    image

    從結(jié)果發(fā)現(xiàn)獲取的只有init方法,主要是因?yàn)樵?swift.h文件中暴露出來(lái)的只有init方法

  • 如果想讓OC能使用腻惠,必須類繼承NSObject + @objc修飾屬性环肘、方法

    image
  • 如果去掉@objc修飾屬性,將方法改成dynamic修飾集灌,是否可以打印方法悔雹?

    image

    從結(jié)果可以看出,依舊不能被OC獲取到欣喧,需要修改為@objc dynamic修飾

    image

結(jié)論

  • 對(duì)于純swift類來(lái)說(shuō)腌零,沒有 動(dòng)態(tài)特性dynamic(因?yàn)?code>swift是靜態(tài)語(yǔ)言),方法和屬性不加任何修飾符的情況下唆阿,已經(jīng)不具備runtime特性益涧,此時(shí)的方法調(diào)度,依舊是函數(shù)表調(diào)度即V_Table調(diào)度

  • 對(duì)于純swift類驯鳖,方法和屬性添加@objc標(biāo)識(shí)的情況下闲询,可以通過(guò)runtime API獲取到久免,但是在OC中是無(wú)法進(jìn)行調(diào)度的,原因是因?yàn)?code>swift.h文件中沒有swift類的聲明

  • 對(duì)于繼承自NSObject類來(lái)說(shuō)嘹裂,如果想要?jiǎng)討B(tài)的獲取當(dāng)前屬性+方法妄壶,必須在其聲明前添加 @objc關(guān)鍵字,如果想要使用方法交換寄狼,還必須在屬性+方法前添加dynamic關(guān)鍵字丁寄,否則當(dāng)前屬性+方法只是暴露給OC使用,而不具備任何動(dòng)態(tài)特性

objc源碼驗(yàn)證

(由于xcode12.2暫時(shí)無(wú)法運(yùn)行objc源碼泊愧,下列驗(yàn)證圖片僅供參考)

  • 進(jìn)入class_copyMethodList源碼,斷住伊磺,查看此時(shí)的cls,其中data()存儲(chǔ)類的信息

    image
  • 進(jìn)入data删咱,打印bits屑埋、superclass

    image

    從這里可以得出swift中有默認(rèn)基類,即_SwiftObject

  • 打印methods

    image
  • swift源碼中搜索_SwiftObject痰滋,繼承自NSObject摘能,在內(nèi)存結(jié)構(gòu)上與OC基本類似的

#if __has_attribute(objc_root_class)
__attribute__((__objc_root_class__))
#endif
SWIFT_RUNTIME_EXPORT @interface SwiftObject<NSObject> {
 @private
  Class isa;
  //refCounts
  SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;
}

  • 在swift類的結(jié)構(gòu)中,其中TargetAnyClassMetadata繼承自TargetHeapMetaData敲街,其中只有一個(gè)屬性kind团搞,TargetAnyClassMetadata有四個(gè)屬性:isa、superclass多艇、cacheData逻恐、data即bits

    image

    所以swift為了保留和OC交互,其在底層存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)上和OC是一致的

  • objc源碼中搜索swift_class_t峻黍,繼承自objc_class复隆,保留了OC模板類的4個(gè)屬性,其次才是自己的屬性

struct swift_class_t : objc_class {
    uint32_t flags;
    uint32_t instanceAddressOffset;
    uint32_t instanceSize;
    uint16_t instanceAlignMask;
    uint16_t reserved;

    uint32_t classSize;
    uint32_t classAddressOffset;
    void *description;
    // ...

    void *baseAddress() {
        return (void *)((uint8_t *)this - classAddressOffset);
    }
};

問(wèn)題:為什么繼承NSObject姆涩?:必須通過(guò)NSObject聲明挽拂,來(lái)幫助編譯器判斷,當(dāng)前類是一個(gè)和OC交互的類

4骨饿、元類型轻局、AnyClass、Self

AnyObject

  • AnyObject:代表任意類的instance样刷、類的類型仑扑、僅類遵守的協(xié)議
class CJLTeacher: NSObject {
    var age: Int = 18
}

var t = CJLTeacher()

//此時(shí)代表的就是當(dāng)前CJLTeacher的實(shí)例對(duì)象
var t1: AnyObject = t

//此時(shí)代表的是CJLTeacher這個(gè)類的類型
var t2: AnyObject = CJLTeacher.self

//繼承自AnyObject,表示JSONMap協(xié)議只有類才可以遵守
protocol JSONMap: AnyObject { }

例如如果是結(jié)構(gòu)體遵守協(xié)議置鼻,會(huì)報(bào)錯(cuò)

image

需要將struct修改成class

//繼承自AnyObject镇饮,表示JSONMap協(xié)議只有類才可以遵守
protocol JSONMap: AnyObject {

}
class CJLJSONMap: JSONMap {

}

Any

  • Any:代表任意類型,包括 function類型 或者Optional類型,可以理解為AnyObjectAny的子集
//如果使用AnyObject會(huì)報(bào)錯(cuò)箕母,而Any不會(huì)
var array: [Any] = [1, "cjl", "", true]

AnyClass

  • AnyClass:代表任意實(shí)例的類型 储藐,類型是AnyObject.Type
    • 查看定義,是public typealias AnyClass = AnyObject.Type

T.self & T.Type

  • T.self

    • 如果T是實(shí)例對(duì)象俱济,返回的就是它本身

    • 如果T是類,那么返回的是MetaData

  • T.Type:一種類型钙勃,

  • T.selfT.Type類型

//此時(shí)的self類型是  CJLTeacher.Type
var t = CJLTeacher.self

打印結(jié)果如下

  • 查看t1蛛碌、t2存儲(chǔ)的是什么?
var t = CJLTeacher()
//實(shí)例對(duì)象地址:實(shí)例對(duì)象.self 返回實(shí)例對(duì)象本身
var t1 = t.self
//存儲(chǔ)metadata元類型
var t2 = CJLTeacher.self

image

type(of:)

  • type(of:):用來(lái)獲取一個(gè)值的動(dòng)態(tài)類型
<!--demo1-->
var age = 10 as NSNumber
print(type(of: age))

<!--打印結(jié)果-->
__NSCFNumber

<!--demo2-->
//value - static type 靜態(tài)類型:編譯時(shí)期確定好的
//type(of:) - dynamic type:Int
var age = 10
//value的靜態(tài)類型就是Any
func test(_ value: Any){

    print(type(of: value))
}

test(age)

<!--打印結(jié)果-->
Int

實(shí)踐

demo1

請(qǐng)問(wèn)下面這段代碼的打印結(jié)果是什么辖源?

class CJLTeacher{
    var age = 18
    var double = 1.85
    func teach(){
        print("LGTeacher teach")
    }
}
class CJLPartTimeTeacher: CJLTeacher {
    override func teach() {
        print("CJLPartTimeTeacher teach")
    }
}

func test(_ value: CJLTeacher){
    let valueType = type(of: value)
    value.teach()
    print(value)
}
var t = CJLPartTimeTeacher()
test(t)

<!--打印結(jié)果-->
CJLPartTimeTeacher teach
CJLTest.CJLPartTimeTeacher

demo2

請(qǐng)問(wèn)下面代碼的打印結(jié)果是什么蔚携?

protocol TestProtocol {

}
class CJLTeacher: TestProtocol{
    var age = 18
    var double = 1.85
    func teach(){
        print("LGTeacher teach")
    }
}

func test(_ value: TestProtocol){
    let valueType = type(of: value)
    print(valueType)
}
var t = CJLTeacher()
let t1: TestProtocol = CJLTeacher()
test(t)
test(t1)

<!--打印結(jié)果-->
CJLTeacher
CJLTeacher

  • 如果將test中參數(shù)的類型修改為泛型,此時(shí)的打印是什么克饶?
func test<T>(_ value: T){
    let valueType = type(of: value)
    print(valueType)
}

<!--打印結(jié)果-->
CJLTeacher
TestProtocol

從結(jié)果中發(fā)現(xiàn)酝蜒,打印并不一致,原因是因?yàn)楫?dāng)有協(xié)議矾湃、泛型時(shí)亡脑,當(dāng)前的編譯器并不能推斷出準(zhǔn)確的類型,需要將value轉(zhuǎn)換為Any邀跃,修改后的代碼如下:

func test<T>(_ value: T){
    let valueType = type(of: value as Any)
    print(valueType)
}

<!--打印結(jié)果-->
CJLTeacher
CJLTeacher

demo3

在上面的案例中霉咨,如果class_getClassMethod中傳t.self,可以獲取方法列表嗎拍屑?

func test(){
    var methodCount: UInt32 = 0
    let methodList = class_copyMethodList(t.self, &methodCount)
    for i in 0..<numericCast(methodCount) {
        if let method = methodList?[I]{
            let methodName = method_getName(method)
            print("方法列表:\(methodName)")
        }else{
            print("not found method")
        }
    }

    var count: UInt32 = 0
    let proList = class_copyPropertyList(CJLTeacher.self, &count)
    for i in 0..<numericCast(count) {
        if let property = proList?[I]{
            let propertyName = property_getName(property)
            print("屬性成員屬性:\(property)")
        }else{
            print("沒有找到你要的屬性")
        }
    }
    print("test run")
}
test()

從結(jié)果運(yùn)行看途戒,并不能,因?yàn)?code>t.self是實(shí)例對(duì)象本身丽涩,即CJLTeacher,并不是CJLTeacher.Type類型

總結(jié)

  • 當(dāng)無(wú)弱引用時(shí)裁蚁,HeapObject中的refCounts等于 strongCount + unownedCount

  • 當(dāng)有弱引用時(shí)矢渊,HeapObject中的refCounts等于 object + xxx + (strongCount + unownedCount) + weakCount

  • 循環(huán)應(yīng)用可以通過(guò)weak / unowned修飾參數(shù)來(lái)解決

  • swift中閉包的捕獲列表值拷貝,即深拷貝枉证,是一個(gè)只讀的常量

  • swift由于是靜態(tài)語(yǔ)言矮男,所以屬性、方法在不加任何修飾符的情況下時(shí)是不具備動(dòng)態(tài)性即Runtime特性的室谚,此時(shí)的方法調(diào)度是V-Table函數(shù)表調(diào)度

  • 如果想要OC使用swift類中的方法毡鉴、屬性,需要class繼承NSObject秒赤,并使用@objc修飾

  • 如果想要使用方法交換猪瞬,除了繼承NSObject+@objc修飾,還必須使用dynamic修飾

  • Any:任意類型入篮,包括function類型陈瘦、optional類型

  • AnyObject:任意類的instance、類的類型潮售、僅類遵守的協(xié)議痊项,可以看作是Any的子類

  • AnyClass:任意實(shí)例類型锅风,類型是AnyObject.Type

  • T.self:如果T是實(shí)例對(duì)象,則表示它本身鞍泉,如果是類皱埠,則表示metadata.T.self的類型是T.Type

參考:http://www.reibang.com/p/0cc765a325cb

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市咖驮,隨后出現(xiàn)的幾起案子边器,更是在濱河造成了極大的恐慌,老刑警劉巖游沿,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饰抒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡诀黍,警方通過(guò)查閱死者的電腦和手機(jī)袋坑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)眯勾,“玉大人枣宫,你說(shuō)我怎么就攤上這事〕曰罚” “怎么了也颤?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)郁轻。 經(jīng)常有香客問(wèn)我翅娶,道長(zhǎng),這世上最難降的妖魔是什么好唯? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任竭沫,我火速辦了婚禮,結(jié)果婚禮上骑篙,老公的妹妹穿的比我還像新娘蜕提。我一直安慰自己,他們只是感情好靶端,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布谎势。 她就那樣靜靜地躺著,像睡著了一般杨名。 火紅的嫁衣襯著肌膚如雪脏榆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天台谍,我揣著相機(jī)與錄音姐霍,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛镊折,可吹牛的內(nèi)容都是我干的胯府。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼恨胚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼骂因!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起赃泡,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤寒波,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后升熊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俄烁,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年级野,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了页屠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蓖柔,死狀恐怖辰企,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情况鸣,我是刑警寧澤牢贸,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站镐捧,受9級(jí)特大地震影響潜索,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜懂酱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一竹习、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧玩焰,春花似錦由驹、人聲如沸芍锚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)并炮。三九已至默刚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逃魄,已是汗流浹背荤西。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邪锌。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓勉躺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親觅丰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饵溅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

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