14-Swift自動(dòng)引用計(jì)數(shù)(循環(huán)引用的解決)

swift使用自動(dòng)引用計(jì)數(shù)(ARC)機(jī)制來(lái)跟蹤和管理應(yīng)用程序的內(nèi)存琴许。一般情況下税肪,swift內(nèi)存管理機(jī)制會(huì)一直起作用,即開(kāi)發(fā)者無(wú)需考慮內(nèi)存管理榜田。ARC會(huì)在類的實(shí)例不再使用時(shí)益兄,即沒(méi)有引用的時(shí)候,自動(dòng)釋放其所占用的內(nèi)存串慰。
?但是要注意偏塞,引用計(jì)數(shù)僅僅應(yīng)用在類的實(shí)例,因?yàn)榻Y(jié)構(gòu)體和枚舉類型是值類型邦鲫,不是引用類型灸叼,也不是通過(guò)引用的方式存儲(chǔ)和傳遞的神汹。

一、自動(dòng)引用計(jì)數(shù)的工作機(jī)制


當(dāng)在創(chuàng)建一個(gè)類的實(shí)例時(shí)古今,ARC會(huì)分配一個(gè)內(nèi)存用于存儲(chǔ)實(shí)例的信息屁魏。內(nèi)存中會(huì)包含實(shí)例的類型信息,以及這個(gè)實(shí)例中所有相關(guān)屬性的值捉腥。
?當(dāng)實(shí)例不再被使用時(shí)氓拼,ARC會(huì)釋放該實(shí)例所占用的內(nèi)存,并讓釋放的內(nèi)存挪作他用抵碟。這即是確保了不再被使用的實(shí)例桃漾,不會(huì)一直占用內(nèi)存空間。
?為了確保使用中的實(shí)例不會(huì)被銷毀拟逮,ARC會(huì)跟蹤和計(jì)算每個(gè)實(shí)例正在被多少屬性撬统、變量和常量所引用,只要是實(shí)例還有被引用敦迄,ARC就不會(huì)銷毀該實(shí)例恋追。

不論是將實(shí)例賦值給屬性、常量還是變量罚屋,它們都會(huì)創(chuàng)建對(duì)此實(shí)例的強(qiáng)引用苦囱。強(qiáng)引用就是將實(shí)例牢牢的保持住,只要是有強(qiáng)引用脾猛,實(shí)例就不會(huì)被銷毀!!!

二撕彤、自動(dòng)引用計(jì)數(shù)實(shí)踐


以下是展示自動(dòng)引用計(jì)數(shù)的工作機(jī)制:

class Student {
    let name:String
    init(name:String) { // 構(gòu)造器
        self.name = name;
        print("名字的初始值為:\(name)");
    }

    deinit {    // 析構(gòu)器
        print("實(shí)例將會(huì)被釋放 --- \(name)");
    }
}

// 定義三個(gè)學(xué)生變量,類型是Student?尖滚,注意是可選類型
var student1:Student?;
var student2:Student?;
var student3:Student?;
// 實(shí)例化喉刘,注意這里就是一個(gè)強(qiáng)引用
// // 此時(shí)Student實(shí)例強(qiáng)引用計(jì)數(shù)為1
student1 = Student(name: "張三");
print("學(xué)生姓名: \(student1!.name)");
// 賦值操作
student2 = student1; // 此時(shí)Student實(shí)例強(qiáng)引用計(jì)數(shù)為2
student3 = student1; // 此時(shí)Student實(shí)例強(qiáng)引用計(jì)數(shù)為3
// 通過(guò)設(shè)置變量為`nil`,即是斷開(kāi)強(qiáng)引用
student1 = nil; // 此時(shí)Student實(shí)例強(qiáng)引用計(jì)數(shù)為2
student2 = nil; // 此時(shí)Student實(shí)例強(qiáng)引用計(jì)數(shù)為1

// 注意看打印效果漆弄,此時(shí)Student實(shí)例是沒(méi)有被使用的睦裳,因?yàn)閌deinit`析構(gòu)器中代碼還沒(méi)被調(diào)用

// 當(dāng)student3設(shè)置為`nil`時(shí),此時(shí)Student實(shí)例強(qiáng)引用計(jì)數(shù)為0
student3 = nil;
// 當(dāng)沒(méi)有強(qiáng)引用的時(shí)候撼唾,才會(huì)被銷毀

輸出結(jié)果:
名字的初始值為:張三
學(xué)生姓名: 張三
實(shí)例將會(huì)被釋放 --- 張三

三廉邑、類實(shí)例之間引起的循環(huán)引用


如果兩個(gè)類實(shí)例相互持有對(duì)方的強(qiáng)引用,這即是循環(huán)引用倒谷。解決辦法就是通過(guò)定義類之間關(guān)系為弱引用無(wú)主引用蛛蒙,以代替強(qiáng)引用(下面會(huì)有實(shí)際解決實(shí)例,這里先了解循環(huán)引用是怎么產(chǎn)生的)渤愁。

/** 
 Student學(xué)生類: 具體某個(gè)學(xué)生牵祟,哪個(gè)班級(jí)
 Grade班級(jí)類: 具體班級(jí),班級(jí)里的學(xué)生有誰(shuí)
 */
class Student {
    // 學(xué)生名字
    let name:String
    // 構(gòu)造器
    init(name:String) {
        self.name = name
    }

    // 哪個(gè)班級(jí)
    var grade:Grade?

    // 析構(gòu)器
    deinit {
        print("實(shí)例將會(huì)被釋放 --- \(name)");
    }
}

class Grade {
    // 哪個(gè)班級(jí)
    let gradeName:String
    //構(gòu)造器
    init(gradeName:String) {
        self.gradeName = gradeName
    }

    // 班級(jí)中的學(xué)生
    var student:Student?

    // 析構(gòu)器
    deinit {
        print("實(shí)例將會(huì)被釋放 --- \(gradeName)");
    }
}

// 學(xué)生: 張三
var student:Student? = Student(name: "張三")
// 班級(jí): 一年一班
var grade:Grade? = Grade(gradeName: "一年一班")

// 張三是在一年一班
student!.grade = grade
// 一年一班中的學(xué)生
grade!.student = student

// 設(shè)置為`nil`抖格,因?yàn)樗鼈兌际强蛇x類型的
student = nil
grade = nil

// 但是Student和Grade的析構(gòu)器都沒(méi)調(diào)用诺苹,說(shuō)明它們的實(shí)例是沒(méi)有被釋放

開(kāi)始咕晋,實(shí)例化操作,那么此時(shí)對(duì)應(yīng)類的實(shí)例都只有一個(gè)強(qiáng)引用所指向(圖中實(shí)線就表示強(qiáng)引用):

之后收奔,是賦值操作student!.grade = gradegrade!.student = student掌呜,此時(shí):


最后,設(shè)置student = nilgrade = nil坪哄,此時(shí):

從上可以看到质蕉,StudentGrade的實(shí)例都是有強(qiáng)引用,即實(shí)例不會(huì)被釋放掉翩肌,那么這也就會(huì)造成內(nèi)存的泄漏模暗。

四、解決實(shí)例之間的循環(huán)引用


swift提供了兩種辦法用來(lái)解決循環(huán)引用的問(wèn)題:弱引用無(wú)主引用摧阅。
?弱引用和無(wú)主引用允許循環(huán)引用中的一個(gè)實(shí)例引用和另一個(gè)實(shí)例而不是保持強(qiáng)引用汰蓉,這也就不會(huì)產(chǎn)生循環(huán)引用問(wèn)題绷蹲。
?對(duì)于生命周期中會(huì)為nil的實(shí)例使用弱引用棒卷。但對(duì)于初始化值后不會(huì)再被賦值為nil的實(shí)例,則使用無(wú)主引用祝钢。

  • 弱引用比规,是不會(huì)阻止ARC銷毀被引用的實(shí)例,或者說(shuō)弱引用是不計(jì)數(shù)是不會(huì)加一操作的拦英。當(dāng)聲明屬性或變量時(shí)蜒什,在前面加上weak關(guān)鍵字表明一個(gè)弱引用。
// 注: 與上面代碼一樣疤估,只是在定義student屬性時(shí)灾常,進(jìn)行了弱化操作
class Grade {
    // 哪個(gè)班級(jí)
    let gradeName:String
    // 構(gòu)造器
    init(gradeName:String) {
        self.gradeName = gradeName
    }

    // 班級(jí)中的學(xué)生
    // var student:Student?
    // 弱引用操作,解決實(shí)例之間的循環(huán)引用
    weak var student:Student?

    // 析構(gòu)器
    deinit {
        print("實(shí)例將會(huì)被釋放 --- \(gradeName)");
    }
}

當(dāng)設(shè)置student = nilgrade = nil的時(shí)候(注意圖中標(biāo)注的先后順序铃拇。另外只要實(shí)例沒(méi)有強(qiáng)引用钞瀑,那么會(huì)被釋放):

注意1: 弱引用必須被聲明為變量,表明其值能在運(yùn)行時(shí)被修改?独蟆5袷病!另外显晶,弱引用可以沒(méi)有值贷岸,所以也必須將弱引用聲明為可選類型。而swift中也是推薦使用可選類型來(lái)描述可能沒(méi)有值的類型磷雇。
注意2: 在使用垃圾收集的系統(tǒng)里偿警,弱指針有時(shí)候來(lái)實(shí)現(xiàn)簡(jiǎn)單的緩沖機(jī)制,因?yàn)闆](méi)有強(qiáng)引用的對(duì)象只會(huì)在內(nèi)存壓力觸發(fā)垃圾收集時(shí)才會(huì)被銷毀唯笙。但ARC中螟蒸,一旦值的最后一個(gè)強(qiáng)引用被刪除落剪,就會(huì)被立即銷毀,這導(dǎo)致弱引用并不適合上面的用途尿庐。

  • 無(wú)主引用忠怖,與弱引用類似,無(wú)主引用也不會(huì)牢牢保持住引用的實(shí)例抄瑟。但與弱引用不同的是凡泣,無(wú)主引用永遠(yuǎn)是有值的!Fぜ佟鞋拟!因此無(wú)主引用總是被定義為非可選類型。而在聲明屬性或變量時(shí)惹资,在前面加上unowned關(guān)鍵字來(lái)表示是一個(gè)無(wú)主引用贺纲。由于無(wú)主引用是非可選類型,你不需要再使用它的時(shí)候?qū)⑺归_(kāi)褪测,無(wú)主引用總是可以被直接訪問(wèn)猴誊。但ARC無(wú)法再實(shí)例被實(shí)例銷毀后將無(wú)主引用設(shè)置為nil,因?yàn)榉强蛇x類型的變量不允許被賦值為nil侮措。

注意: 如果你試圖在實(shí)例被銷毀后懈叹,訪問(wèn)該實(shí)例的無(wú)主引用,會(huì)導(dǎo)致程序崩潰分扎。使用無(wú)主引用澄成,必須要確保引用始終指向一個(gè)未銷毀的實(shí)例。

/** 無(wú)主引用
 例如銀行顧客Customer和信用卡CreditCard畏吓;
 一個(gè)人可以有或沒(méi)有信用卡墨状,但一張信用卡必須與一個(gè)客戶關(guān)聯(lián);
 */
// 銀行顧客
class Customer {
    // 用戶名
    let name:String
    // 用戶對(duì)應(yīng)的信用卡菲饼,可選類型表示可以有卡肾砂,也可以沒(méi)有卡
    var card:CreditCard?

    init(name:String) {
        self.name = name
    }
    deinit {
        print("銀行顧客-實(shí)例被銷毀 --- \(self.name)")
    }
}

// 信用卡
class CreditCard {
    // 卡號(hào)
    let number:UInt64
    // 無(wú)主引用,避免循環(huán)引用(非可選類型巴粪,信用卡實(shí)例必須與一個(gè)客戶關(guān)聯(lián))
    unowned let customer:Customer

    init(number:UInt64, customer:Customer) {
        self.number = number
        self.customer = customer
    }
    deinit {
        print("信用卡-實(shí)例被銷毀 --- \(self.number)")
    }
}

// 銀行客戶通今,張三(可選類型,是可以設(shè)置為`nil`)
var zhangsan:Customer? = Customer(name:"張三");
// 張三的信用卡【注意肛根,初始化的時(shí)候?qū)⒖ㄌ?hào)與張三實(shí)例傳進(jìn)去】
zhangsan!.card = CreditCard(number: 1234_5678_9101_1121,customer: zhangsan!)

// 設(shè)置為空辫塌,即斷開(kāi)對(duì)Customer實(shí)例的引用,檢查是否會(huì)正常釋放
zhangsan = nil

輸出結(jié)果:
銀行顧客-實(shí)例被銷毀 --- 張三
信用卡-實(shí)例被銷毀 --- 1234567891011121

銀行客戶與信用卡綁定后派哲,它們之間的關(guān)系:

之后臼氨,設(shè)置zhangsan = nil,此時(shí)Customer實(shí)例張三沒(méi)有強(qiáng)引用芭届,那么會(huì)被釋放储矩。而Customer實(shí)例張三釋放以后感耙,CreditCard實(shí)例也就沒(méi)有強(qiáng)引用,也會(huì)被釋放持隧,如圖所示:

  • 無(wú)主引用以及隱式解析可選屬性即硼。StudentGrade示例中,兩個(gè)屬性的值都允許為nil屡拨,并存在循環(huán)引用只酥,這種場(chǎng)景最適合弱引用解決;CustomerCreditCard示例中,一個(gè)屬性允許設(shè)置為nil,而另外一個(gè)屬性是不允許為nil际插,并存在循環(huán)引用,這種常見(jiàn)最適合無(wú)主引用解決绝编;而當(dāng)兩個(gè)屬性都必須有值,并初始化完成后將都不會(huì)為nil貌踏,這種場(chǎng)景需要一個(gè)類使用無(wú)主屬性十饥,另外一個(gè)類使用隱式解析可選屬性來(lái)解決:
/** 
 無(wú)主引用以及隱式解析可選屬性
 Country國(guó)家和City城市;
 每個(gè)國(guó)家必須有首都哩俭,而每個(gè)城市必須屬于一個(gè)國(guó)家绷跑;
 */
// 國(guó)家類
class Country {
    // 國(guó)家名
    let name:String
    // 首都城市,是隱式解析可選類型(默認(rèn)是為空凡资,這是不展開(kāi)都可使用)
    var capitalCity:City!
    init(name:String, capitalName:String) {
        // 指定國(guó)家名
        self.name = name
        // 指定首都城市,傳入城市名以及國(guó)家實(shí)例
        self.capitalCity = City(name:capitalName, country: self)
    }  
    deinit {
        print("Country實(shí)例被釋放 --- \(name)")
    }
}
// 城市類
class City {
    // 城市名
    let name:String
    // 所屬首都谬运,是無(wú)主類型
    unowned let country:Country

    init(name:String, country:Country) {
        self.name = name
        self.country = country
    }
    deinit {
        print("City實(shí)例被釋放 --- \(name)")
    }
}
var country = Country(name: "中國(guó)", capitalName: "北京")
print("\(country.name) - \(country.capitalCity.name)")
輸出結(jié)果:
中國(guó) - 北京

五隙赁、閉包引起的循環(huán)引用


在閉包賦值給類實(shí)例的某個(gè)屬性時(shí)也會(huì)有強(qiáng)引用。閉包體中可能訪問(wèn)實(shí)例的某個(gè)屬性梆暖,例如self.someProperty伞访,或者閉包調(diào)用了實(shí)例中的某個(gè)方法,例如self.someMethod轰驳,這都會(huì)導(dǎo)致閉包"捕獲"self,從而產(chǎn)生了循環(huán)引用:

/** 
 閉包的循環(huán)引用
 */
class Person {
    // 名字
    let name:String

    // 懶加載厚掷,自我介紹
    lazy var speakStr:Void -> String = {
        // 閉包中
        return "大家好,我叫\(zhòng)(self.name)"
    }

    init(name:String) {
        self.name = name
    }
    deinit {
        print("Person實(shí)例釋放 --- \(name)");
    }
}

// 初始化
var zhangsan:Person? = Person(name: "張三")
// 調(diào)用
print(zhangsan!.speakStr())

// 斷開(kāi)對(duì)Person實(shí)例的引用级解,但此時(shí)Person實(shí)例不會(huì)被銷毀
zhangsan = nil

六冒黑、解決閉包引起的循環(huán)引用


對(duì)于閉包所引起的循環(huán)引用,在swift中提供了一種解決辦法勤哗,即是閉包捕獲列表抡爹。在定義閉包同時(shí)定義捕獲列表作為閉包的一部分,通過(guò)這種方式可以解決閉包和類實(shí)例之間的循環(huán)引用芒划。捕獲列表定義了閉包體內(nèi)捕獲一個(gè)或多個(gè)引用類型的規(guī)則冬竟,這與解決兩個(gè)類之間的循環(huán)引用一樣欧穴,聲明每個(gè)捕獲的引用為弱引用或無(wú)主引用,而不是強(qiáng)引用泵殴。
?在閉包中需要注意的是涮帘,只要在閉包中要使用本對(duì)象中的屬性或方法,就必須要使用self.somePropertyself.someMethod()笑诅,而不能使用somePropertysomeMethod()焚辅。
?定義捕獲列表,在捕獲列表中的每一項(xiàng)都由需要加上weakunowned關(guān)鍵字苟鸯。
?在閉包和捕獲的實(shí)例總是相互引用時(shí)并且是同時(shí)銷毀時(shí)同蜻,可以將閉包內(nèi)的捕獲定義為無(wú)主引用。
?而在被捕獲的引用可能會(huì)為nil時(shí)早处,將閉包內(nèi)的捕獲定義為弱引用湾蔓。弱引用總是可選類型,并且當(dāng)引用的實(shí)例被銷毀后砌梆,弱引用的值會(huì)自動(dòng)置為nil默责。
?如果是被捕獲的引用絕對(duì)不會(huì)變?yōu)?code>nil,應(yīng)該用無(wú)主引用咸包,而不是引用桃序。

// 閉包有參數(shù)列表和返回類型的定義,把捕獲列表放在前面
lazy var someClosure:(Int, String) -> String = {
  [unowned self, weak delegate = self.delegate!] (index:Int ,stringToProcess:String) -> String in
    // 閉包中對(duì)應(yīng)操作
}

// 閉包沒(méi)有指定參數(shù)列表或返回類型烂瘫,即會(huì)通過(guò)上下文推斷媒熊,那么可以把捕獲列表和關(guān)鍵字`in`放在閉包最開(kāi)始地方
lazy var someClosure:Void -> String = {
  [unowned self, weak delegate = self.delegate!] in 
    // 閉包中對(duì)應(yīng)操作
}

class Person {
    // 名字
    let name:String

    // 懶加載,自我介紹
    lazy var speakStr:Void -> String = {
        // 解決循環(huán)引用坟比,即表示"用無(wú)主引用而不是強(qiáng)引用來(lái)捕獲self"
        [unowned self] in
        // 閉包中
        return "大家好芦鳍,我叫\(zhòng)(self.name)"
    }

    init(name:String) {
        self.name = name
    }
    deinit {
        print("Person實(shí)例釋放 --- \(name)");
    }
}

// 初始化
var zhangsan:Person? = Person(name: "張三")
// 調(diào)用
print(zhangsan!.speakStr())

// 斷開(kāi)對(duì)Person實(shí)例的引用,此時(shí)Person實(shí)例就會(huì)被銷毀
zhangsan = nil
輸出結(jié)果:
大家好葛账,我叫張三
Person實(shí)例釋放 --- 張三

注:xcode7.3環(huán)境

作者:西門奄
鏈接:http://www.reibang.com/u/77035eb804c3
來(lái)源:簡(jiǎn)書
簡(jiǎn)書著作權(quán)歸作者所有柠衅,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末籍琳,一起剝皮案震驚了整個(gè)濱河市菲宴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌趋急,老刑警劉巖喝峦,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異宣谈,居然都是意外死亡愈犹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)漩怎,“玉大人勋颖,你說(shuō)我怎么就攤上這事⊙福” “怎么了饭玲?”我有些...
    開(kāi)封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)叁执。 經(jīng)常有香客問(wèn)我茄厘,道長(zhǎng),這世上最難降的妖魔是什么谈宛? 我笑而不...
    開(kāi)封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任次哈,我火速辦了婚禮,結(jié)果婚禮上吆录,老公的妹妹穿的比我還像新娘窑滞。我一直安慰自己,他們只是感情好恢筝,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布哀卫。 她就那樣靜靜地躺著,像睡著了一般撬槽。 火紅的嫁衣襯著肌膚如雪此改。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天侄柔,我揣著相機(jī)與錄音共啃,去河邊找鬼。 笑死勋拟,一個(gè)胖子當(dāng)著我的面吹牛勋磕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播敢靡,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼苦银!你這毒婦竟也來(lái)了啸胧?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤幔虏,失蹤者是張志新(化名)和其女友劉穎纺念,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體想括,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陷谱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烟逊。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡渣窜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宪躯,到底是詐尸還是另有隱情乔宿,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布访雪,位于F島的核電站详瑞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏臣缀。R本人自食惡果不足惜坝橡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望精置。 院中可真熱鬧计寇,春花似錦、人聲如沸氯窍。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)狼讨。三九已至贝淤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間政供,已是汗流浹背播聪。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留布隔,地道東北人离陶。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像衅檀,于是被迫代替她去往敵國(guó)和親招刨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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