swift的指針介紹,指針的常用函數(shù)和使用

OC指針

在OC中的對象Object我們都是用的指針殴玛,像下面這些:

NSString *str = ...;
NSObject *obj = ...;
NSArray *array = @[];

很顯然在OC中我們使用*來表示對象擎宝,其實是聲明指針郁惜,而且使用&符號來取地址水评,比如我們在使用C的數(shù)組時猩系,可以直接使用指針的+、- 來獲得當(dāng)前元素的下一個或上一個元素(這里是指針的加減而不是地址的加減中燥,指針+1可能地址跳了一位或者一個字節(jié)甚至更多):(代碼a0)

int nums[2] =  {1,3,5};
printf("%d",*nums);  //1
printf("%d",*(nums+1));  //3

//32513 = 0111 1111 0000 0001
int32_t num = 32513;
int8_t *num8s;
//取 num 地址賦給指針 num8s
num8s = #
//0000 0001 =  1
int num_1 = *num8s;  //1
//0111 1111 =  127
int num_2 = *(num8s+1);  //127

看上面代碼寇甸,我們給num賦值32513,然后取num地址賦給了指針num8s疗涉,int8_t這個類型是8位整形拿霉,這時候我們就相當(dāng)于把num這個數(shù)字拆分為每8位為一個元素的數(shù)組(這里的int32_t是4字節(jié),32位)咱扣,數(shù)組容量為4绽淘,我們用二進制表示的話就是:
0...0, 0...0, 01111111, 00000001
因為iphone是小端序,低地址存儲數(shù)值低位偏窝,所以拆成數(shù)組就是:
int8_t num8s[4] = {1,127,0,0};
我們獲取*num8s相當(dāng)于num8s[0]等于1收恢,獲取*(num8s+1)相當(dāng)于num8s[1]=127。


對于swift語言來說祭往,他也有指針,不過沒有OC指針那么方便的使用火窒,接下來我們講講swift里的指針使用硼补,以及用swift指針怎么實現(xiàn)上面那段代碼里的拆分內(nèi)存并讀取。

swift指針

首先先來了解下swift有哪幾種指針的類:

UnsafePointer
UnsafeRawPointer
UnsafeBufferPointer
UnsafeRawBufferPointer
//還有他們對應(yīng)的Mutable形式
UnsafeMutablePointer
...

mutable形式的指針有更多的可操作性熏矿,是以下講的重點已骇。

  • UnsafeMutablePointer:常用指針類,要求綁定存儲的類型票编,通常的類對象褪储、實例對象、基本類型都可以用這種指針(類似NSString *, UILabel *,NSObject *)慧域。
  • UnsafeMutableRawPointer:原始指針類鲤竹,不需要綁定存儲類型(類似void *)。
  • UnsafeMutableBufferPointer:集合類對象指針昔榴,swift對集合類指針有單獨的函數(shù)和屬性(類似NSArray<Pointee> *,NSSet<Pointee> *,NSDictionary<keyPointee, valuePointee> *)辛藻,有count,startIndex互订,endIndex等屬性吱肌。
  • UnsafeMutableRawBufferPointer:原始buffer指針,可以理解為BufferPointer的首地址仰禽。
指針的獲取

在OC中我們用&獲取指針氮墨,用(void *)number強制類型轉(zhuǎn)換把整數(shù)轉(zhuǎn)為指針纺蛆,這就是我們在OC中指針的獲取和創(chuàng)建了,
那么我們在swift中如何獲取指針呢

首先swift中變量用var聲明,常量用let來聲明:

  • let聲明的常量都存儲在數(shù)據(jù)區(qū)规揪,且不允許再改變值
  • var聲明的變量犹撒,要看是什么類型,object類存在堆區(qū)粒褒,獨立的基本類型(附加在類中的屬性不算在此)存在棧中
    舉例說明识颊,如下:代碼(b0)
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //32513 = 0111 1111 0000 0001
        // let number:Int16 = 32513
        var number: Int16 = 32513
        var label = UILabel()
        label.text = "aHaha"
        label.font = UIFont.systemFont(ofSize: 17)
  }
}
  • 當(dāng)number聲明為let時,他的地址是0x117e295b0的數(shù)據(jù)區(qū)地址奕坟;

  • 當(dāng)number聲明為var時祥款,他的地址就是0x7ffee69288a8的棧區(qū)地址,
    此時number是直接尋址月杉,即棧地址對應(yīng)的內(nèi)存中直接存儲了數(shù)據(jù):

    number的直接尋址圖.png

  • var聲明的label是間接尋址刃跛,局部變量指針是0x7ffee69288a0的棧地址,棧地址內(nèi)存儲的是堆地址0x7fdc0cd088b0,堆地址中存儲了label的實際內(nèi)容:

    label的間接尋址圖.png



    上面我們知道了對象變量大都存儲在堆中苛萎,獨立基本類型大都存儲在棧中桨昙,下面我們再看指針的獲取方法。
    1.基本類型的指針
    使用swift.Misc庫中withUnsafe...方法臨時獲取指針腌歉,前提必須是可變變量var:

let raw_number = withUnsafePointer(to: &number, {  bb -> Int in
     return Int(bitPattern: bb)
})

如果是聲明為let的常量那么編譯會報錯蛙酪,因為let常量存儲在數(shù)據(jù)區(qū),數(shù)據(jù)區(qū)除了常量還有APP代碼等翘盖,為了安全性考慮不允許修改內(nèi)容(在debug時桂塞,let常量可以在控制臺輸出po withUnsafePointer(to: &number, {bb->Int in return Int(bitPattern: bb)})):

withUnsafePointer函數(shù)參數(shù)為常量的報錯.png

需要注意的是我們這里return出來的是 Int 值,原因是withUnsafePointer這類函數(shù)的閉包中獲取的指針都是臨時指針馍驯,不能在閉包外使用阁危,這Int值我們可以繼續(xù)處理成指針:

let number_pointer = UnsafePointer<Int16>.init(bitPattern: raw_number)
number_pointer?.pointee == number //true



2.object對象的指針
我們拿 代碼(b0) 中的label舉例,label是一個對象汰瘫,那么獲取指針的方法就很多了:

        let label_UnsafeMutableRawPointer = Unmanaged.passUnretained(label).toOpaque()
        
        let label_unsafeBitCast_Int = unsafeBitCast(label, to: Int.self)
        let with_raw_label = withUnsafeMutablePointer(to: &label) { (wp) -> Int in
            return Int(bitPattern: wp)
        }

//對于直接尋址的number來說狂打,使用unsafeBitCast方法獲取到的就是number局部變量對應(yīng)指針的內(nèi)存中的值,
//因為是直接尋址混弥,所以就是數(shù)值 32513
        let number_bitCast = unsafeBitCast(number, to: Int16.self)
  • 對于實例對象label來說趴乡,可以使用非托管類的passUnretained方法來創(chuàng)建一個非托管對象,然后獲取其原始指針地址剑逃。
  • 使用swift.C庫函數(shù)unsafeBitCast浙宜,這個方法就是獲取label局部變量指針對應(yīng)內(nèi)存中的值,因為是間接尋址蛹磺,實際獲得的是label對應(yīng)在堆內(nèi)存中的地址(這里返回的是Int值)140583084525744粟瞬,轉(zhuǎn)為16進制就是7fdc0cd088b0(在上文的 label間接尋址圖 有)。
  • 使用swift.Misc庫的withUnsafeMutablePointer函數(shù)萤捆,獲取臨時指針裙品,這里獲取到的是label局部變量指針即棧指針140732766783648俗批,轉(zhuǎn)16進制就是7ffee69288a0(在 label的間接尋址圖 有),再通過Int(bitPattern:)函數(shù)獲取到指針地址的Int值市怎。

對于上面獲取的label_UnsafeMutableRawPointer岁忘,我們可以轉(zhuǎn)為常用的指針類型UnsafeMutablePointer:(代碼b1)

let heap_labelPointer = label_UnsafeMutableRawPointer.bindMemory(to: UILabel.self, capacity: 1)

對于我們獲取到的label的兩個指針地址Int值:棧指針0x7ffee69288a0和堆指針0x7fdc0cd088b0(指針地址的Int值,不是指針)区匠,到底怎么使用干像,使用哪個呢?看:(代碼b2)

let stack_labelPointer = UnsafeMutablePointer.init(bitPattern: with_raw_label)
let heap_labelPointer = UnsafeMutablePointer.init(bitPattern: label_unsafeBitCast_Int)

stack_labelPointer.pointee == label //true
heap_labelPointer.pointee == label //false

對于指針UnsafeMutablePointer來說驰弄,指針本身作為一個結(jié)構(gòu)體有一個內(nèi)存麻汰,結(jié)構(gòu)體中的pointee用來存儲指針?biāo)赶虻膬?nèi)容。
上面代碼中stack_labelPointer是用label的臨時指針地址初始化的戚篙,stack_labelPointer.pointee就是label五鲫;
heap_labelPointer.pointee卻不是label,要知道label_unsafeBitCast_Int是label在堆中的存儲地址岔擂,所以我們用label_unsafeBitCast_Int來初始化指針導(dǎo)致這個結(jié)構(gòu)體本身就是label(因為結(jié)構(gòu)體和類的一些相似性位喂,不會報錯),pointee就不是指向label了乱灵。
那么heap_labelPointer.pointee不是label是什么呢:(代碼b3)

        let what = heap_labelPointer!.pointee
        //這里正常輸出塑崖,label不是一個類對象,而是一個實例對象
        let label_notClassObject = label as? AnyClass == .none

      //下面兩句都是true,第一句證明what是UILabel的類對象阔蛉,
      //第二句證明what可以調(diào)用UILabel的類方法areAnimationsEnabled,
      //綜上what確實是UILabel類對象
        let what_isUILabelClass = what as? AnyClass == Optional.some(UILabel.self)
        let what_hadUILabelClassMethod:String = what.responds(to: #selector(getter: UILabel.areAnimationsEnabled)) ? "true":"false"

通過上面的代碼我們發(fā)現(xiàn)heap_labelPointer.pointee就相當(dāng)于在OC中的'isa'弃舒,OC中l(wèi)abel對象的isa是UILabel,這里 pointee 也是指向UILabel類對象状原,并且可以調(diào)用UILabel的類方法。
這里僅當(dāng)是OC中存在的NSObject時苗踪,堆指針地址的.pointee才是指向類對象颠区,如果是其他對象,那么在強制轉(zhuǎn)為指針的過程中通铲,其 ‘pointee’ 在指針結(jié)構(gòu)體中的偏移地址(為0) 對應(yīng)在內(nèi)存中地址就是.pointee(作為NSObject時毕莱,pointee偏移地址為0,剛好對應(yīng)isa)。

3.數(shù)組的指針

var numbers:[Int] = [7,3,2,4,0]

對于數(shù)組numbers來說颅夺,他的存儲有兩部分朋截,一部分是數(shù)組的標(biāo)識、屬性等吧黄,一部分是數(shù)組元素部服,一般數(shù)組元素就存儲在數(shù)組標(biāo)識、屬性等的相鄰內(nèi)存(鄰接數(shù)組ContiguousArray就是這種存儲方式)拗慨±耍看:(代碼c0)

        //獲取局部變量numbers的指針(&numbers)奉芦,棧指針
        let stack_raw_numbers = withUnsafePointer(to: &numbers, { (bb) -> Int in
            return Int(bitPattern: bb)
        })
        //numbers 存儲在堆中地址,該存儲地址不是數(shù)組元素首地址剧蹂,而是以數(shù)組標(biāo)識屬性等開始的數(shù)組內(nèi)存
        let heap_raw_numbers = unsafeBitCast(numbers, to: Int.self)
        //numbers 可以直接作為 UnsafeRawPointer 使用, 獲取 數(shù)組元素存儲的首地址
        let raw_numbers = Int(bitPattern: numbers)

對于上面的三個指針地址声功,我們實際用到的一般只有兩個:stack_raw_numbers 和 raw_numbers ,這兩個就是獲取數(shù)組元素的兩種方法宠叼,使用如下:(代碼c1)

        //1.取局部變量棧指針先巴,通過該指針的pointee來指向數(shù)組
        var numbersPointer_test = UnsafeMutablePointer<[Int]>.init(bitPattern: stack_raw_numbers)
        let get_numbers = numbersPointer_test!.pointee

        //2.取數(shù)組元素存儲區(qū)的首地址,即數(shù)組第一個元素的地址
        let numbersPointer_0 = UnsafeMutablePointer<Int>.init(bitPattern: raw_numbers)
        //之后的元素可以根據(jù)元素地址冒冬,向后推移
        let numbersPointer_1 = numbersPointer![1]
        let numbersPointer_2 = numbersPointer![2]
         //也可以直接使用元素首地址初始化bufferPointer
        var numbers_bufferPointer = UnsafeMutableBufferPointer.init(start: numbersPointer, count: 5)
  • 使用stack_raw_numbers來初始化指針可以直接用pointee;
  • 使用數(shù)組元素首地址初始化指針伸蚯,該指針指向第一個元素,第二個元素可以用numbersPointer![1]來表示窄驹,以此類推朝卒;
    還可以根據(jù)首地址初始化numbers_bufferPointer,numbers_bufferPointer[0] == 7,numbers_bufferPointer[1] == 3 ...

對于heap_raw_numbers來說乐埠,他是數(shù)組的首地址(直接指向數(shù)組標(biāo)識抗斤、屬性等),但是數(shù)組內(nèi)元素實際上是存儲在旁邊內(nèi)存里(鄰接數(shù)組的元素存儲在相鄰內(nèi)存丈咐,一般會相差4個字節(jié)):

        //這里的指針本身就是指向數(shù)組了瑞眼,這導(dǎo)致調(diào)用pointee反而出錯,pointee并不指向數(shù)組元素
        var what_numbers_pointer = UnsafeMutablePointer<[Int]>.init(bitPattern: heap_raw_numbers)
//跟 代碼b3 類似棵逊,不過這里不是OC對象NSArray伤疙,而是swift對象Array
        let some_what_numbersPointer = what_numbers_pointer!.pointee


指針的創(chuàng)建

上面我們講了根據(jù)現(xiàn)有對象初始化指針,這里我們講指針的創(chuàng)建辆影,這兩者最大的區(qū)別就是指針創(chuàng)建需要申請內(nèi)存徒像,這個指針如果使用label來初始化,那他也不是原來的label了蛙讥,他是一個新的 存儲在指針 .pointee 內(nèi)的對象锯蛀。

指針一般用allocte來創(chuàng)建,需要注意的是capacity參數(shù)是容量的意思次慢,非集合指針一般設(shè)為1,

struct SYPerson {
    var name: String
    var age: Int
}

    let systructPointer = UnsafeMutablePointer<SYPerson>.allocate(capacity: 1)

initialize來初始化旁涤,如果類型是基本類型,那么可以直接assign迫像,因為內(nèi)存中保存的必定是0或1劈愚,相當(dāng)于已經(jīng)初始化了。
initialize(repeating: obj, count: 1) 可以用 initialize(to: obj)代替闻妓。

//這里是自定義結(jié)構(gòu)體SYPerson菌羽,直接寫assign會崩潰,因為pointee還沒有申請內(nèi)存纷闺,無法拷貝內(nèi)容進去
//systructPointer.assign(repeating: systruct, count: 1)    //wrong
    systructPointer.initialize(repeating: systruct, count: 1)
    systructPointer.initialize(to: systruct)

然后用assign來分配內(nèi)存算凿,如果指針容量大于1份蝴,assign就會將repeating拷貝進內(nèi)存并循環(huán)拷貝count次,count就是repeating的重復(fù)次數(shù)

    systructPointer.assign(repeating: systruct_other, count: 1)
//等同于
    systructPointer[0] = systruct
//等同于
    systructPointer.pointee = systruct

最后在不用的時候deallocate釋放內(nèi)存氓轰。

    systructPointer.deallocate()

實際使用過程中婚夫,所謂allocte就是申請一個指針內(nèi)存,但是這個指針沒有為.pointee準(zhǔn)備好內(nèi)存署鸡,而initialize有為pointee申請內(nèi)存并初始化內(nèi)容案糙;assign則是將新的內(nèi)容拷貝到pointee的內(nèi)存中,
assign是不能用在未初始化的指針上的靴庆,initialize方法介紹上說應(yīng)該使用在未初始化的指針上时捌,但是實際上可以作用在已初始化的指針上。

指針的使用

1.使用下標(biāo)來直接取值:

let systruct = SYPerson(name: "sd", age: 12)
let systructPointer = UnsafeMutablePointer<SYPerson>.allocate(capacity: 1)
systructPointer.initialize(to: systruct)

systructPointer[0].age == 12  //true

對于上面的代碼炉抒,我們可以直接用下標(biāo)取pointee值:systructPointer[0]奢讨。
原變量systruct是let修飾的,但是systructPointer.pointee是新的變量焰薄,是可以修改的:systructPointer[0].name = "changed"拿诸。

var numbers:[Int] = [7,3,2,4,0]
//numbers 可以直接作為 UnsafeRawPointer 使用, 獲取 數(shù)組元素存儲的首地址
        let raw_numbers = Int(bitPattern: numbers)
let numbersPointer = UnsafeMutablePointer<Int>.init(bitPattern: raw_numbers)
numbersPointer![0] == 7  //true
numbersPointer![1] == 3  //true

上面這段代碼是作用在原數(shù)組numbers上的指針,如果指針改變值塞茅,原數(shù)組也會改變亩码。
創(chuàng)建一個新的指針可以這樣:(代碼d0)

let numberPointer_other = UnsafeMutablePointer<Int>.allocate(capacity: 5)
numberPointer_other.initialize(from: &numbers, count: 5)
//等同于
numberPointer_other.initialize(from: numbers, count: 5)

numberPointer_other[0] == 7  //true
numberPointer_other[1] == 3  //true

上面這段代碼根據(jù)已有數(shù)組來創(chuàng)建容量為5的指針,這里使用兩種方式:

  • 使用&numbers表示數(shù)組的局部變量野瘦,棧指針描沟,初始化的時候initialize方法會自動把數(shù)組元素拷貝過去。
  • 直接使用numbers鞭光,numbers可以作為UnsafeRawPointer使用(數(shù)組元素的首地址)吏廉,相當(dāng)于以數(shù)組元素的首地址來初始化新的指針。

數(shù)組也可以用bufferPointer惰许,這在 代碼c0和c1 中已經(jīng)展示了迟蜜,不過方便點的方法還是獲取臨時指針:

numbers.withUnsafeBufferPointer { (bb) in
      bb.first! == 7  //true
      bb[0] == 7  //true
}

2.簡單的說一下指針的一些方法
其實我是故意把這些常用方法放到最后來講。

  • UnsafeMutablePointer:
    .withMemoryRebound(to: Int8.self, capacity: 1) { (bb) -> UnsafeMutablePointer<Int8> in ...}:臨時綁定內(nèi)存啡省,這里綁定了Int8類型,閉包返回Int8類型指針髓霞。
    .deinitialize(count: 1):反初始化卦睹,獲得原始指針rawPointer。
    .advanced(by: n):返回向后移位n位的指針方库,這里一位就表示一個指針類型內(nèi)存结序,如果指針是SYPerson類型,那么就是向后移動n個SYPerson纵潦,即MemoryLayout<SYPerson>.stride * n字節(jié)數(shù)徐鹤。

  • UnsafeMutableRawPointer:
    .bindMemory(to: Int8.self, capacity: 1):返回 將原始指針綁定到類型Int8 的指針垃环。
    .load(as: Int8.self):將原始指針內(nèi)存加載位Int8類型并返回值。

  • UnsafeMutableBufferPointer:
    .last .first:內(nèi)存緩沖區(qū)的第一和最后一個元素返敬。
    index(...):獲取相應(yīng)位置的元素遂庄。
    .baseAddress:返回內(nèi)存緩沖區(qū)的首地址。
    基本可以直接當(dāng)做數(shù)組來操作劲赠。

  • UnsafeMutableRawBufferPointer:
    .last .first:基本單位是一字節(jié)的Int8(格外注意)涛目,如果存儲的是別的類型,需要重新綁定內(nèi)存凛澎。
    .bindMemory(to: Int.self):返回重新綁定為Int類型的BufferPointer指針霹肝。
    .baseAddress:返回內(nèi)存緩沖區(qū)的首地址的原始地址。

3.使用swift指針模仿OC 代碼a0 操作
根據(jù)上面的指針方法塑煎,我們直接取得number指針沫换,綁定Int8類型,然后用advanced方法向后移一字節(jié)最铁,就得到了127:代碼d0

//32513 = 0111 1111 0000 0001
var number: Int16 = 32513
let raw_number = withUnsafePointer(to: &number, {  bb -> Int in
        return Int(bitPattern: bb)
})
let number_pointer = UnsafeMutablePointer<Int8>.init(bitPattern: raw_number)
//number_pointer![1] == 127  //true
let number_8_pointer = number_pointer?.advanced(by: 1)
number_8_pointer[0] == 127  //true

//重新創(chuàng)建指針
let unsafeMutablePointer = UnsafeMutablePointer<Int16>.allocate(capacity: 1)
unsafeMutablePointer.initialize(repeating: number, count: 1)
unsafeMutablePointer.withMemoryRebound(to: Int8.self, capacity: 2) { bb in
            bb[1] == 127  //true
}

如果是OC中UIKit類對象讯赏,如UILabel,UIView等炭晒,我們可以直接用
view.hash
獲取原始直接的Int值待逞,如果這些類沒有重寫Hashable協(xié)議,我們還可以用.hashValue

var label = UILabel()
let label_unsafeBitCast_Int = unsafeBitCast(label, to: Int.self)
let raw_value = label.hash
label_unsafeBitCast_Int == raw_value   //true



swift指針相當(dāng)于擴展了OC指針网严,由原本的指向內(nèi)存的地址识樱,變?yōu)榱艘栽摰刂窞槠鹗嫉刂返慕Y(jié)構(gòu)體;由原本的數(shù)值型地址震束,轉(zhuǎn)變?yōu)榱藄wift中的一段內(nèi)存

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怜庸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子垢村,更是在濱河造成了極大的恐慌割疾,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘉栓,死亡現(xiàn)場離奇詭異宏榕,居然都是意外死亡,警方通過查閱死者的電腦和手機侵佃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門麻昼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人馋辈,你說我怎么就攤上這事抚芦。” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵叉抡,是天一觀的道長尔崔。 經(jīng)常有香客問我,道長褥民,這世上最難降的妖魔是什么季春? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮轴捎,結(jié)果婚禮上鹤盒,老公的妹妹穿的比我還像新娘。我一直安慰自己侦副,他們只是感情好侦锯,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秦驯,像睡著了一般尺碰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上译隘,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天亲桥,我揣著相機與錄音,去河邊找鬼固耘。 笑死题篷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的厅目。 我是一名探鬼主播番枚,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼损敷!你這毒婦竟也來了葫笼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拗馒,失蹤者是張志新(化名)和其女友劉穎路星,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诱桂,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡洋丐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了挥等。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垫挨。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖触菜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哀峻,我是刑警寧澤涡相,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布哲泊,位于F島的核電站,受9級特大地震影響催蝗,放射性物質(zhì)發(fā)生泄漏切威。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一丙号、第九天 我趴在偏房一處隱蔽的房頂上張望先朦。 院中可真熱鬧,春花似錦犬缨、人聲如沸喳魏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刺彩。三九已至,卻和暖如春枝恋,著一層夾襖步出監(jiān)牢的瞬間创倔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工焚碌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畦攘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓十电,卻偏偏與公主長得像知押,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子摆出,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

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

  • 跳蚤市場 昨晚讓她挑一些自己想要賣的東西朗徊,挑來挑去只有幾件她小舅舅的古董玩具,自己的即使再破爛一件也不舍得賣偎漫。汗爷恳!...
    Joyce_kexin閱讀 90評論 0 1
  • 這樣想通了以后,次日二人再去養(yǎng)老院看望奶奶時象踊,就著重強調(diào)給奶奶温亲,"過去你們有很多過節(jié)和不悅,自古婆媳也確實難處杯矩,到...
    東隅之桑閱讀 3,903評論 2 2
  • 明誠的思緒一下子回到了從前栈虚。 他從小便是孤兒,不知道自己的父母是誰史隆?一直住在孤兒院里魂务,直到兩歲,一位女人突然出現(xiàn)。...
    空谷飄零閱讀 3,509評論 2 15