Swift - 類和結(jié)構(gòu)體

在面向過程的語言中,要想實(shí)現(xiàn)類似類的功能只能借助結(jié)構(gòu)體,其實(shí)從OC源碼也能看出來,類的組成本就是復(fù)雜的結(jié)構(gòu)體實(shí)現(xiàn)的罪既。
而在Swift中結(jié)構(gòu)體的功能被擴(kuò)大化了,基本擁有了和類差不多的功能:

  • 定義屬性
  • 定義方法
  • 定義getter和setter
  • 可以定義初始化器來設(shè)置初始狀態(tài)
  • 實(shí)現(xiàn)擴(kuò)展的功能
  • 遵循協(xié)議,并實(shí)現(xiàn)協(xié)議的方法
  • 結(jié)構(gòu)總是被復(fù)制窗看,并且不使用引用計(jì)數(shù)。

類具有結(jié)構(gòu)不具備的附加功能:

  • 繼承允許一個類繼承另一個類的特征。
  • 類型轉(zhuǎn)換使您能夠在運(yùn)行時檢查和解釋類實(shí)例的類型惰爬。
  • 初始化器使一個類的實(shí)例能夠釋放它所分配的任何資源。
  • 引用計(jì)數(shù)允許多個引用到一個類實(shí)例辜王。
定義結(jié)構(gòu)體和類
class className {

}

struct structName {

}

我們?yōu)轭惡徒Y(jié)構(gòu)體添加一些變量和方法:

struct Resolution {
    var width = 0
    var height = 0
    
    func resolutionFun() {
        print("method of struct Resolution")
    }
}

class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
    
    func VideoMode() {
        print("method of class VideoMode")
    }
}

類和結(jié)構(gòu)體的初始化

定義是一回事,初始化又是另一回事劈狐。我們來看如何初始化它們:
let object Name = Class Name()
let variable Name = Struct Name()

let someResolution = Resolution()
let someVideoMode = VideoMode()
訪問屬性

Swift中訪問屬性使用的是鏈?zhǔn)浇Y(jié)構(gòu),訪問屬性的時候使用 .
object name.propertyName

print("The width of someResolution is \(someResolution.width)")
print("The width of someVideoMode is \(someVideoMode.resolution.width)")

類或者結(jié)構(gòu)中的屬性默認(rèn)情況是可寫可讀的:

someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")

關(guān)于直接修改類中結(jié)構(gòu)的數(shù)據(jù),這一點(diǎn)與OC是不同的,OC中并沒有處理好這一層級關(guān)系,導(dǎo)致類的中結(jié)構(gòu)體是只讀的呐馆,無法去修改肥缔。而Swift允許您直接設(shè)置結(jié)構(gòu)屬性的子屬性。

結(jié)構(gòu)體的初始化

所有結(jié)構(gòu)都有一個自動生成的成員智能初始化器汹来,您可以使用它來初始化新結(jié)構(gòu)實(shí)例的成員屬性:

struct Resolution {
    var width = 0
    var height = 0
}

let resolution = Resolution(width:100,height:120)
print("width:\(resolution.width),height:\(resolution.height)")
結(jié)果:
width:100,height:120

而類并不具備這樣的初始化器,如果需要特定的初始化需要去自定義,那么如何創(chuàng)建類似這樣的初始化器呢?
首先要知道初始化器是系統(tǒng)本身的方法,我們只能去重寫或者重載它

class VideoMode {
    var _name: String
    
    init(){
        _name = "Jin"
    }
}

let videoModeNormal = VideoMode()
print("name:\(videoModeNormal._name)")
結(jié)果:
name:Jin

我們重寫了系統(tǒng)默認(rèn)的init()初始化方法,并且設(shè)定我們想定義的功能续膳。

那么我們?nèi)绾稳?shí)現(xiàn)像結(jié)構(gòu)體那樣的初始功能呢?
這時候我們需要用到重載功能.
重載就是將父類已有的方法通過擴(kuò)充參數(shù)的形式重新定義一遍。
我們可以看一下對比:

class VideoMode {
    var _name: String
    
    init(){
        _name = "Jin"
    }
    
    init(name:String){
        _name = name;
    }
    
}

let videoModeNormal = VideoMode()
print("name:\(videoModeNormal._name)")
let videoModeCustom = VideoMode(name: "Jack")
print("name:\(videoModeCustom._name)")
結(jié)果:
name:Jin
name:Jack

我們類中申明了兩個初始化方法,通過我們在實(shí)例化的時候使用不同的初始化方式,系統(tǒng)會自動識別使用哪個方法收班。
例如調(diào)用VideoMode()的時候系統(tǒng)會調(diào)用init()方法,調(diào)用VideoMode(name: "Jack")的時候坟岔,系統(tǒng)會調(diào)用 init(name:String)方法。
當(dāng)然,struct的初始化方法也是可以這樣實(shí)現(xiàn)的:

struct Resolution {
    var width: Double
    
    init(){
        width = 100
    }
    
    init(width:Double){
        self.width = width;
    }
    
}

let resolutionNormal = Resolution()
print("width:\(resolutionNormal.width)")
let resolutionCustom = Resolution(width: 120)
print("width:\(resolutionCustom.width)")
結(jié)果:
width:100.0
width:120.0

調(diào)用init初始化方法,必須初始化結(jié)構(gòu)體或者類中所有的屬性摔桦。當(dāng)然,如果該屬性定義的時候已經(jīng)初始化可以不用炮车。
初始化可以參數(shù)下面的設(shè)定

    var width: Double = 0
    var height: Double = 0
    
    init(){
        width = 100
    }

如果你像下面這樣寫,會報出:Return from initializer without initializing all stored properties(提示你返回的時候,并沒有將所有屬性初始化)的錯誤

    var width: Double = 0
    var height: Double 
    
    init(){
        width = 100
    }
類的初始化

上面大致了解了結(jié)構(gòu)體的初始化,還有一些類的初始化.雖然兩者很多地方是相同.但總有一些不同的地方.
class 的設(shè)定中,初始化分為了指定初始化(Designated initializers)和便利初始化(Convenience initializers).
指定初始化就是我們上面講的:

init(parameters) {
statements
}

而便利初始化是無法獨(dú)立運(yùn)作的。它設(shè)定是這樣的:

convenience init(parameters) {
statements
}

我們可以是實(shí)驗(yàn)一下:

class Resolution {
    var width: Double = 0
    var height: Double = 0
    
    init(){
        width = 100
    }
    
   convenience init(height:Double){
        self.height = height;
    }  
}

會報錯:
Use of 'self' in property access 'height' before self.init initializes self
Self.init isn't called on all paths before returning from initializer
這兩個錯誤簡單來說反應(yīng)的就是這個init目前來說并不具備系統(tǒng)的init功能,它其實(shí)只是我們自定義的方法,但因?yàn)槭褂昧薸nit關(guān)鍵字,系統(tǒng)就無法理解這種行為了酣溃。 而要想讓它發(fā)生作用,我們需要它本身加入init方法的功能瘦穆。

   convenience init(height:Double){
        self.init()
        self.height = height;
    }  

這樣就可以了。
而Swift本生也指定了這樣的規(guī)則:

  • Rule 1
    A designated initializer must call a designated initializer from its immediate superclass.
    指定的初始化器必須從其直接的超類調(diào)用指定的初始化器赊豌。
  • Rule 2
    A convenience initializer must call another initializer from the same class.
    一個convenience修飾的初始化器必須從同一個類調(diào)用另一個初始化器扛或。
  • Rule 3
    A convenience initializer must ultimately call a designated initializer.
    一個convenience修飾的初始化器必須最終調(diào)用一個指定的初始化器。
    這些規(guī)則如下圖所示:
initializerDelegation.png

在上圖中碘饼,超類有一個指定的初始化器和兩個方便的初始化器熙兔。一個方便初始化器調(diào)用另一個方便初始化器,它依次調(diào)用單個指定的初始化器艾恼。這滿足了上面的規(guī)則2和3住涉。超類本身沒有進(jìn)一步的超類,因此規(guī)則1不適用钠绍。

這個圖中的子類有兩個指定的初始化器和一個方便的初始化器舆声。方便初始化器必須調(diào)用兩個指定的初始化器中的一個,因?yàn)樗荒軓耐粋€類調(diào)用另一個初始化器柳爽。這滿足了上面的規(guī)則2和3媳握。兩個指定的初始化器都必須從超類調(diào)用單個指定的初始化器,以滿足上面的規(guī)則1磷脯。

這些規(guī)則不會影響您的類的用戶如何創(chuàng)建每個類的實(shí)例蛾找。上圖中的任何初始化器都可以用來創(chuàng)建它們所屬的類的完全初始化實(shí)例。這些規(guī)則只會影響您如何編寫類的初始化器的實(shí)現(xiàn)赵誓。

下圖顯示了四個類的更復(fù)雜的類層次結(jié)構(gòu)打毛。它演示了這個層次結(jié)構(gòu)中指定的初始化器如何充當(dāng)類初始化的“漏斗”點(diǎn)柿赊,簡化了鏈中的類之間的相互關(guān)系:

initializerDelegation02.png

看似復(fù)雜的關(guān)系,其實(shí)也很簡單。
父類的init方法是會被繼承的,而它的子類如果選擇繼承父類的初始化方法,而想創(chuàng)建convenience修飾的初始化器幻枉,就必然需要使用各自類中的init方法闹瞧。

兩階段初始化

Class initialization in Swift is a two-phase process. In the first phase, each stored property is assigned an initial value by the class that introduced it. Once the initial state for every stored property has been determined, the second phase begins, and each class is given the opportunity to customize its stored properties further before the new instance is considered ready for use.
Swift中的類初始化是一個兩階段過程。在第一階段中展辞,每個存儲的屬性都由引入它的類分配一個初始值。一旦確定了每個存儲屬性的初始狀態(tài)万牺,第二個階段就開始了罗珍,并且每個類都有機(jī)會在新實(shí)例準(zhǔn)備好使用之前進(jìn)一步定制它的存儲屬性。

The use of a two-phase initialization process makes initialization safe, while still giving complete flexibility to each class in a class hierarchy. Two-phase initialization prevents property values from being accessed before they are initialized, and prevents property values from being set to a different value by another initializer unexpectedly.
使用兩階段的初始化過程使初始化更加安全脚粟,同時仍然為類層次結(jié)構(gòu)中的每個類提供完全的靈活性覆旱。兩階段初始化防止在初始化前訪問屬性值,并防止屬性值被另一個初始化器設(shè)置為不同的值核无。

Swift’s two-phase initialization process is similar to initialization in Objective-C. The main difference is that during phase 1, Objective-C assigns zero or null values (such as 0 or nil) to every property. Swift’s initialization flow is more flexible in that it lets you set custom initial values, and can cope with types for which 0 or nil is not a valid default value.
Swift的兩階段初始化過程類似于在Objective-C中初始化扣唱。主要的區(qū)別在于,在第1階段团南,Objective-C中對每個屬性都賦值0或null值(例如0或nil)噪沙。Swift的初始化流更靈活,它允許您設(shè)置自定義的初始值吐根,并且可以處理0或nil不是有效的默認(rèn)值的類型正歼。

Swift的編譯器執(zhí)行四個有用的安全檢查,以確保兩階段的初始化是沒有錯誤的完成的:

  • Safety check 1
    A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.
    一個指定的初始化器必須確保它的類所引入的所有屬性在它委托給一個超類初始化器之前被初始化拷橘。
  • As mentioned above, the memory for an object is only considered fully initialized once the initial state of all of its stored properties is known. In order for this rule to be satisfied, a designated initializer must make sure that all of its own properties are initialized before it hands off up the chain.
    正如上面所提到的局义,只有當(dāng)所有存儲屬性的初始狀態(tài)被知道時,對象的內(nèi)存才會被完全初始化冗疮。為了讓這個規(guī)則得到滿足萄唇,一個指定的初始化器必須確保所有的屬性都在它被連接到鏈之前被初始化。
  • Safety check 2
    A designated initializer must delegate up to a superclass initializer before assigning a value to an inherited property. If it doesn’t, the new value the designated initializer assigns will be overwritten by the superclass as part of its own initialization.
    指定的初始化器必須在將一個值賦值給繼承屬性之前將其委托給一個超類初始化器术幔。如果沒有另萤,指定初始化器分配的新值將被超類作為其自身初始化的一部分重寫。
  • Safety check 3
    A convenience initializer must delegate to another initializer before assigning a value to any property (including properties defined by the same class). If it doesn’t, the new value the convenience initializer assigns will be overwritten by its own class’s designated initializer.
    一個便利的初始化器必須委托給另一個初始化器诅挑,然后將一個值賦給任何屬性(包括由同一個類定義的屬性)仲墨。如果它不這樣做,那么方便初始化器分配的新值將被它自己的類的指定初始化器重寫揍障。
  • Safety check 4
    An initializer cannot call any instance methods, read the values of any instance properties, or refer to self as a value until after the first phase of initialization is complete.
    一個初始化器不能調(diào)用任何實(shí)例方法目养,讀取任何實(shí)例屬性的值,或者將self作為一個值毒嫡,直到初始化的第一階段完成癌蚁。
  • The class instance is not fully valid until the first phase ends. Properties can only be accessed, and methods can only be called, once the class instance is known to be valid at the end of the first phase.
    類實(shí)例在第一個階段結(jié)束之前是不完全有效的幻梯。只有當(dāng)類實(shí)例在第一階段的末尾是有效的時,才可以訪問屬性努释,并且只能調(diào)用方法碘梢。

下面是第一階段如何查找一個假設(shè)的子類和超類的初始化調(diào)用:


第一階段安全檢查.png

下面是兩階段的初始化是如何進(jìn)行的,基于上面的四個安全檢查:
階段 1

  • A designated or convenience initializer is called on a class.
    在類上調(diào)用指定的或方便的初始化器伐蒂。
  • Memory for a new instance of that class is allocated. The memory is not yet initialized.
    為該類的一個新實(shí)例的內(nèi)存分配煞躬。內(nèi)存還沒有初始化。
  • A designated initializer for that class confirms that all stored properties introduced by that class have a value. Thememory for these stored properties is now initialized.
    這個類的指定初始化器確認(rèn)了該類所引入的所有存儲屬性都有一個值逸邦。這些存儲屬性的內(nèi)存現(xiàn)在已經(jīng)被初始化了恩沛。
  • The designated initializer hands off to a superclass initializer to perform the same task for its own stored properties.
    指定的初始化器交給一個超類初始化器,為它自己的存儲屬性執(zhí)行相同的任務(wù)缕减。
  • This continues up the class inheritance chain until the top of the chain is reached.
    這將繼續(xù)繼承類繼承鏈雷客,直到到達(dá)鏈的頂端。
  • Once the top of the chain is reached, and the final class in the chain has ensured that all of its stored properties have a value, the instance’s memory is considered to be fully initialized, and phase 1 is complete.
    一旦到達(dá)鏈的頂端桥狡,并且鏈中的最后一個類確保其所有的存儲屬性都有一個值搅裙,實(shí)例的內(nèi)存就被認(rèn)為是完全初始化的,而階段1是完整的裹芝。

這里的鏈就是class.classProperty 通過 .連接起來的結(jié)構(gòu)

階段2

  • Working back down from the top of the chain, each designated initializer in the chain has the option to customize the instance further. Initializers are now able to access self and can modify its properties, call its instance methods, and so on.
    從鏈的頂部向下工作部逮,鏈中的每個指定初始化器都可以選擇進(jìn)一步自定義實(shí)例。初始化器現(xiàn)在能夠訪問self并可以修改它的屬性嫂易,調(diào)用它的實(shí)例方法甥啄,等等。
  • Finally, any convenience initializers in the chain have the option to customize the instance and to work with self.
    最后炬搭,鏈中的任何方便的初始化器都可以選擇自定義實(shí)例并與self一起工作蜈漓。

下面是第2階段如何查找相同的初始化調(diào)用:


第二階段安全檢查.png

官網(wǎng)給出的解釋很是詳盡的解釋了初始化的工作步驟,雖然枯燥,但確實(shí)必須的。從這層工作中也看到了Swift相比于OC的安全和穩(wěn)定性更加出色,比起OC更多時候因?yàn)橐馔鈱?dǎo)致的崩潰情況,Swift在這方面的檢查機(jī)制要更加全面一點(diǎn)宫盔。

初始化器繼承和重寫

與Objective-C中的子類不同融虽,Swift子類在默認(rèn)情況下不會繼承父類初始化器。

Swift’s approach prevents a situation in which a simple initializer from a superclass is inherited by a more specialized subclass and is used to create a new instance of the subclass that is not fully or correctly initialized.
Swift的方法防止了一種情況灼芭,即一個超類的簡單初始化器是由一個更專門化的子類繼承而來的有额,它被用來創(chuàng)建一個未完全或正確初始化的子類的新實(shí)例。

當(dāng)您編寫一個與超類指定初始化器相匹配的子類初始化器時彼绷,您實(shí)際上對指定的初始化器進(jìn)行重寫巍佑。因此,您必須在子類的初始化器定義之前編寫override修飾符寄悯。

class Vehicle {
    var numberOfWheels = 0
}

class Bicycle: Vehicle {
    override init() {
        super.init()
        numberOfWheels = 2
    }
}
自動初始化繼承

As mentioned above, subclasses do not inherit their superclass initializers by default. However, superclass initializers are automatically inherited if certain conditions are met. In practice, this means that you do not need to write initializer overrides in many common scenarios, and can inherit your superclass initializers with minimal effort whenever it is safe to do so.
正如上面提到的萤衰,子類在默認(rèn)情況下不會繼承父類初始化器。但是猜旬,如果滿足某些條件脆栋,超類初始化器就會自動繼承倦卖。在實(shí)踐中,這意味著您不需要在許多常見的場景中重寫初始化器椿争,并且可以在安全的情況下以最小的工作量來繼承您的超類初始化器怕膛。

假設(shè)您為您在子類中引入的任何新屬性提供了默認(rèn)值,下面的兩個規(guī)則適用:

  • 規(guī)則1
    如果你的子類沒有定義任何指定的初始化器秦踪,它會自動繼承所有父類指定的初始化器褐捻。
  • 規(guī)則2
    如果您的子類提供了所有超類指定的初始化器的實(shí)現(xiàn),或者通過它們實(shí)現(xiàn)繼承并遵守規(guī)則1椅邓,或者通過提供自定義實(shí)現(xiàn)作為其定義的一部分柠逞,那么它就會自動繼承所有超類的方便初始化器。
總結(jié)
  • You can use both classes and structures to define custom data types to use as the building blocks of your program’s code.
    您可以使用類和結(jié)構(gòu)來定義定制的數(shù)據(jù)類型希坚,以作為程序代碼的構(gòu)建塊。
  • However, structure instances are always passed by value, and class instances are always passed by reference. This means that they are suited to different kinds of tasks. As you consider the data constructs and functionality that you need for a project, decide whether each data construct should be defined as a class or as a structure.
    但是陵且,結(jié)構(gòu)實(shí)例總是通過值傳遞裁僧,而類實(shí)例總是通過引用傳遞。這意味著它們適用于不同類型的任務(wù)慕购。當(dāng)您考慮一個項(xiàng)目需要的數(shù)據(jù)結(jié)構(gòu)和功能時聊疲,決定每個數(shù)據(jù)結(jié)構(gòu)是否應(yīng)該被定義為一個類或一個結(jié)構(gòu)。

As a general guideline, consider creating a structure when one or more of these conditions apply:
指導(dǎo)方針沪悲,考慮在一個或多個條件適用的情況下創(chuàng)建一個結(jié)構(gòu):

  • The structure’s primary purpose is to encapsulate a few relatively simple data values.
    結(jié)構(gòu)體的主要目的是封裝一些相對簡單的數(shù)據(jù)值获洲。
  • It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
    這是當(dāng)您合理的分配或傳遞該結(jié)構(gòu)的實(shí)例時,封裝的值將被復(fù)制殿如,而不是被引用贡珊。
  • Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
    結(jié)構(gòu)中存儲的任何屬性都是值類型,它也可以被復(fù)制涉馁,而不是被引用门岔。
  • The structure does not need to inherit properties or behavior from another existing type.
    結(jié)構(gòu)體不需要從另一個現(xiàn)有類型繼承屬性或行為。

優(yōu)秀的結(jié)構(gòu)體例子包括:

  • The size of a geometric shape, perhaps encapsulating a width property and a height property, both of type Double.
    幾何形狀的大小烤送,可能是封裝了寬度屬性和高度屬性寒随,兩者都是Double類型。
  • A way to refer to ranges within a series, perhaps encapsulating a start property and a length property, both of type Int.
    一種表示范圍內(nèi)的范圍的方法帮坚,可能是封裝一個起始屬性和一個長度屬性妻往,這兩種類型都是Int類型。
  • A point in a 3D coordinate system, perhaps encapsulating x, y and z properties, each of type Double.
    In all other cases, define a class, and create instances of that class to be managed and passed by reference. In practice, this means that most custom data constructs should be classes, not structures.
    三維坐標(biāo)系中的一個點(diǎn)试和,可能是封裝x讯泣、y和z的屬性,每一種類型都是雙精度的阅悍。
    在所有其他情況下判帮,定義一個類局嘁,并創(chuàng)建該類的實(shí)例,以便通過引用來管理和傳遞晦墙。在實(shí)踐中悦昵,這意味著大多數(shù)自定義數(shù)據(jù)結(jié)構(gòu)應(yīng)該是類,而不是結(jié)構(gòu)晌畅。

In Swift, many basic data types such as String, Array, and Dictionary are implemented as structures. This means that data such as strings, arrays, and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.
在Swift中但指,許多基本的數(shù)據(jù)類型,如字符串抗楔、數(shù)組和字典都是作為結(jié)構(gòu)實(shí)現(xiàn)的棋凳。這意味著當(dāng)將字符串、數(shù)組和字典等數(shù)據(jù)分配給新的常量或變量時连躏,或者當(dāng)它們被傳遞給函數(shù)或方法時滑废,就會復(fù)制這些數(shù)據(jù)。

This behavior is different from Foundation: NSString, NSArray, and NSDictionary are implemented as classes, not structures. Strings, arrays, and dictionaries in Foundation are always assigned and passed around as a reference to an existing instance, rather than as a copy.
這種行為與Foundation庫不同:NSString坎吻、NSArray和NSDictionary都是作為類實(shí)現(xiàn)的解总,而不是結(jié)構(gòu)。Foundation中的字符串勺良、數(shù)組和字典總是被分配和傳遞绰播,作為對現(xiàn)有實(shí)例的引用,而不是作為副本尚困。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蠢箩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子事甜,更是在濱河造成了極大的恐慌谬泌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逻谦,死亡現(xiàn)場離奇詭異呵萨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)跨跨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門潮峦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勇婴,你說我怎么就攤上這事忱嘹。” “怎么了耕渴?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵拘悦,是天一觀的道長。 經(jīng)常有香客問我橱脸,道長础米,這世上最難降的妖魔是什么分苇? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮屁桑,結(jié)果婚禮上医寿,老公的妹妹穿的比我還像新娘。我一直安慰自己蘑斧,他們只是感情好靖秩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著竖瘾,像睡著了一般沟突。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捕传,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天惠拭,我揣著相機(jī)與錄音,去河邊找鬼庸论。 笑死职辅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的葡公。 我是一名探鬼主播罐农,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼条霜,長吁一口氣:“原來是場噩夢啊……” “哼催什!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宰睡,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蒲凶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拆内,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旋圆,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年麸恍,在試婚紗的時候發(fā)現(xiàn)自己被綠了灵巧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡抹沪,死狀恐怖刻肄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情融欧,我是刑警寧澤敏弃,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站噪馏,受9級特大地震影響麦到,放射性物質(zhì)發(fā)生泄漏绿饵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一瓶颠、第九天 我趴在偏房一處隱蔽的房頂上張望拟赊。 院中可真熱鬧,春花似錦步清、人聲如沸要门。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽欢搜。三九已至,卻和暖如春谴轮,著一層夾襖步出監(jiān)牢的瞬間炒瘟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工第步, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疮装,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓粘都,卻偏偏與公主長得像廓推,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子翩隧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355

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

  • 他已骨瘦如柴樊展,我也老態(tài)龍鐘。他沒有力量說話堆生,還強(qiáng)睜著眼睛招待我
    CNBLUEone閱讀 157評論 0 0
  • 分手后第三天专缠,做了個決定,既然還能做朋友淑仆,那就再追她一次涝婉。。蔗怠。
    YiQin_閱讀 146評論 0 0
  • 每天上課墩弯、看書、刷題 生活回到夢想開始 光陰好的時候就把自己放進(jìn)世界里 像沙煲湯里放一塊陳皮 ——冰橘氤氳明橙的香...
    麟子寶寶閱讀 134評論 0 0
  • 屋檐下的風(fēng)鈴搖晃 是風(fēng)帶來了消息 你留下的思念 擱淺的曾經(jīng)一涌而來 翻開泛黃的日記本 頁邊是你惡作劇的涂鴉 喃喃自...
    南方有咸魚閱讀 667評論 2 3
  • 今晚小朋友拿出驚奇翻翻書寞射,邊拿邊說好久沒看這本了渔工,今晚錄音這本。以前他要錄這本我都會用各種方式拒絕怠惶,變著法要他換另...
    愛生活繪分享閱讀 182評論 0 0