淺拷貝和深拷貝(copy和mutableCopy)的詳解

一没陡、淺拷貝和深拷貝的定義
關(guān)于淺拷貝和深拷貝是如何定義的小腊,可能不同的人有不同的理解伏尼。據(jù)我了解(不知道有沒有偏差),蘋果對淺拷貝和深拷貝是這么定義的:淺拷貝可以理解為指針復(fù)制堪遂,新的指針并沒有指向一段新開辟的內(nèi)存介蛉,新指針?biāo)赶虻膬?nèi)存跟被拷貝指針?biāo)赶虻膬?nèi)存其實是同一塊內(nèi)存;深拷貝不是指針復(fù)制溶褪,新的指針指向了一段新開辟的內(nèi)存币旧,并且這個新開辟的內(nèi)存的內(nèi)容,跟被拷貝指針?biāo)赶虻膬?nèi)存的內(nèi)容是一樣的猿妈;如果拷貝的是非容器對象吹菱,例如NSString,NSNumber這些,相對來說比較好理解彭则。如果拷貝的是容器對象鳍刷,例如NSArray,NSDictionary,按照蘋果對淺拷貝和深拷貝的定義,對容器對象進(jìn)行所謂的深拷貝俯抖,其實也僅僅是容器的深拷貝输瓜,容器里面的元素,其實還是指針拷貝芬萍;如果要對容器對象實現(xiàn)完全意義上的深拷貝(容器和容器里的元素都是深拷貝尤揣,在內(nèi)存中完全獨(dú)立但內(nèi)容一樣的2份數(shù)據(jù)),則需要通過其他方式柬祠,具體有什么方式北戏,文章最后部分有介紹。

二瓶盛、對象拷貝的幾種情況
要透徹理解淺拷貝和深拷貝最欠,需要分以下幾種類型來討論:
1、不可修改的非容器類(如NSString)
2惩猫、可修改的非容器類(如NSMutableString)
3、不可修改的容器類(如NSArray蚜点、NSDictionary轧房、NSSet)
4、可修改的容器類(如NSMutableArray绍绘、NSMutableDictionary奶镶、NSMutableSet)

三迟赃、系統(tǒng)的非容器類(如NSString,NSMutableString等)
首先看一個例子

- (void)testStringCopyA {
    NSString *string = @"origion";
    NSString *stringCopy = [string copy];
    NSMutableString *stringMCopy = [string mutableCopy];
    NSLog(@"string address: %p stringCopy address:%p stringMCopy address:%p", string, stringCopy, stringMCopy);
    NSLog(@"string retainCount:%ld stringCopy retainCount:%ld stringMCopy retainCount:%ld", [string retainCount], [stringCopy retainCount], [stringMCopy retainCount]);
    [stringMCopy appendString:@"!!"];
    NSLog(@"string: %@ stringCopy: %@ stringMCopy:%@", string, stringCopy, stringMCopy);
}

打印結(jié)果:
string address: 0x1153554b0 stringCopy address:0x1153554b0 stringMCopy address:0x6000006692c0
string retainCount:-1 stringCopy retainCount:-1 stringMCopy retainCount:1
string: origion stringCopy: origion stringMCopy:origion!!

分析:string和stringCopy指向的地址是相同的,而stringMCopy指向的地址則不同厂镇,修改stringMCopy的內(nèi)容后纤壁,string和stringCopy并沒有變化,說明stringMCopy是深拷貝捺信,stringCopy是淺拷貝

再看多一個例子:

- (void)testStringCopyB {
    NSMutableString *string = [[NSMutableString alloc] initWithString:@"origion"];
    NSString *stringCopy = [string copy]; // 注意這里copy返回的是一個不可修改的NSString,而非NSMutableString
    NSMutableString *stringMCopy = [string mutableCopy];
    NSLog(@"string address: %p stringCopy address:%p stringMCopy address:%p", string, stringCopy, stringMCopy);
    NSLog(@"string retainCount:%ld stringCopy retainCount:%ld stringMCopy retainCount:%ld", [string retainCount], [stringCopy retainCount], [stringMCopy retainCount]);
    [stringMCopy appendString:@"!!"];
    NSLog(@"string: %@ stringCopy: %@ stringMCopy:%@", string, stringCopy, stringMCopy);
}

打印結(jié)果:
string address: 0x608000478280 stringCopy address:0xa6e6f696769726f7 stringMCopy address:0x608000478240
string retainCount:1 stringCopy retainCount:-1 stringMCopy retainCount:1
string: origion stringCopy: origion stringMCopy:origion!!
分析:
對NSMutableString調(diào)用copy酌媒,會開辟新的內(nèi)存,說明是深拷貝迄靠,但是返回的是一個不可修改的NSString(不信的話調(diào)用appendString立馬崩潰);
對NSMutableString調(diào)用mutableCopy,會開辟新的內(nèi)存秒咨,說明是深拷貝,返回的是一個可修改的NSMutableString;

四掌挚、不可修改容器NSArray的拷貝
其實怎么定義淺拷貝和深拷貝并非是最重要的雨席,重要的是我們要清楚理解在內(nèi)存層面,到底發(fā)生了什么改變吠式。下面準(zhǔn)備了幾個示例代碼陡厘,分別展示了對NSArray對象進(jìn)行拷貝的幾種可能情況,配合代碼打印結(jié)果和分析特占,方便讀者對比和理解糙置。首先準(zhǔn)備一個用來復(fù)制用的NSArray:

NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];

然后演示ABCDEF共6個例子,對array對象進(jìn)行不同的"拷貝"操作:
示例A:

NSArray *deepCopyArray=[array copy];

示例B:

NSArray *deepCopyArray=[[NSArray alloc] initWithArray:array];

示例C:

NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: NO];

示例D:

NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: YES];

示例E:

NSArray *deepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
                              [NSKeyedArchiver archivedDataWithRootObject: array]];

示例F:

NSArray *deepCopyArray=[array mutableCopy];

1摩钙、示例A

- (void)testArrayDeepCopyA {
    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSArray *deepCopyArray=[array copy];
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x608000253830 deepCopyArray address:0x608000253830
array retainCount: 2 deepCopyArray retainCount: 2
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c
)
deepCopyArray : (
"a,you are changed",
b,
c
)

分析:
1罢低、[array copy] 執(zhí)行之后,deepCopyArray和array所指向的內(nèi)容地址是一樣的胖笛,即是同一個容器网持;
2、[array copy] 執(zhí)行之前, array的retainCount是1长踊,[array copy]執(zhí)行之后功舀,array的retainCount變成2,deepCopyArray的retainCount也是2,由此也可側(cè)面印證兩者指向的就是同一塊內(nèi)存(同一個NSArray容器)
3身弊、修改array的第一個元素的內(nèi)容后辟汰,deepCopyArray的第一個元素的內(nèi)容也跟著變了,證明這兩者指向的就是同一塊內(nèi)存(同一個NSArray容器)

結(jié)論:
上面對NSArray的copy是淺拷貝阱佛,容器和容器里的元素都是一樣的帖汞,唯一的變化就是引用計數(shù)器變成了2。那為什么NSArray的copy不新開辟一段內(nèi)存來做拷貝呢凑术?那是因為NSArray本身是一個不可修改的容器翩蘸,既然不可修改,就沒必要新開辟一段內(nèi)存淮逊,只需要引用計數(shù)器加一就夠了催首,大大節(jié)省了內(nèi)存開銷扶踊。

2、示例B

- (void)testArrayDeepCopyB {
    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSArray *deepCopyArray=[[NSArray alloc] initWithArray:array];
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x600000443b40 deepCopyArray address:0x6000004427c0
array retainCount: 1 deepCopyArray retainCount: 1
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c
)
deepCopyArray : (
"a,you are changed",
b,
c
)

分析:
(略)

結(jié)論:
array和deepCopyArray是不同的容器郎任,但元素卻是相同的秧耗,按蘋果的說法,也叫做深拷貝2爸巍(這里插入一張圖比較合適)

3分井、示例C

- (void)testArrayDeepCopyC {
    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: NO];
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x600000442910 deepCopyArray address:0x600000441380
array retainCount: 1 deepCopyArray retainCount: 1
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c
)
deepCopyArray : (
"a,you are changed",
b,
c
)

分析:
(略)

結(jié)論:
array和deepCopyArray是不同的容器,但元素卻是相同的歼疮,按蘋果的說法杂抽,也叫做深拷貝!(跟示例B的效果是完全一樣的)

4韩脏、示例D

- (void)testArrayDeepCopyD {
    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: YES];
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x6080004435d0 deepCopyArray address:0x608000443150
array retainCount: 1 deepCopyArray retainCount: 1
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c
)
deepCopyArray : (
a,
b,
c
)

分析:(略)

結(jié)論:
array和deepCopyArray是不同的容器缩麸,里面的元素也是不相同的,這就是完全意義上的深拷貝了

5赡矢、示例E

- (void)testArrayDeepCopyE {
    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSArray* deepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
                              [NSKeyedArchiver archivedDataWithRootObject: array]];
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x60000005f980 deepCopyArray address:0x600000245670
array retainCount: 1 deepCopyArray retainCount: 1
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c
)
deepCopyArray : (
a,
b,
c
)

分析:(略)

結(jié)論:
array和deepCopyArray是不同的容器杭朱,里面的元素也是不相同的,這就是完全意義上的深拷貝了(也就是效果跟示例D一樣)

6吹散、示例F

- (void)testArrayDeepCopyF {
    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSArray *deepCopyArray=[array mutableCopy];
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x6000004432d0 deepCopyArray address:0x600000250d70
array retainCount: 1 deepCopyArray retainCount: 1
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c
)
deepCopyArray : (
"a,you are changed",
b,
c
)

分析:
(略)

結(jié)論:
array和deepCopyArray是不同的容器弧械,但元素卻是相同的,按蘋果的說法空民,也叫做深拷貝H刑啤(跟示例B的效果是完全一樣的)

五、可修改的容器類NSMutableArray
上面詳細(xì)的列舉了NSArray拷貝的情況界轩,下面簡單介紹一下NSMutableArray,先看一個例子

- (void)testArrayDeepCopyG {
    NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSMutableArray *deepCopyArray=[array copy]; // 這里返回的是可修改的容器NSMutableArray
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    [array addObject:@"d"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x6000002433c0 deepCopyArray address:0x600000457be0
array retainCount: 1 deepCopyArray retainCount: 1
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c,
d
)
deepCopyArray : (
"a,you are changed",
b,
c
)
分析:(略)

結(jié)論:在這個例子里画饥,不僅修改了容器里的第一個元素的值,還往容器里新增加一個元素浊猾,根據(jù)打印結(jié)果可以知道抖甘,對NSMutableArray調(diào)用copy,是深拷貝葫慎,但僅僅是容器的深拷貝衔彻,容器里的元素是指針拷貝。

再來看另外一個例子偷办,對NSMutableArray進(jìn)行mutableCopy

- (void)testArrayDeepCopyH {
    NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSMutableArray *deepCopyArray=[array mutableCopy];
    
    NSLog(@"array address:%p deepCopyArray address:%p", array, deepCopyArray);
    NSLog(@"array retainCount: %ld deepCopyArray retainCount: %ld",[array retainCount], [deepCopyArray retainCount]);
    
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
    [[array objectAtIndex:0] appendString:@",you are changed"];
    [array addObject:@"d"];
    NSLog(@"\narray : %@ \ndeepCopyArray : %@", array, deepCopyArray);
}

打印結(jié)果:
array address:0x60000044afe0 deepCopyArray address:0x60000024c3f0
array retainCount: 1 deepCopyArray retainCount: 1
array : (
a,
b,
c
)
deepCopyArray : (
a,
b,
c
)
array : (
"a,you are changed",
b,
c,
d
)
deepCopyArray : (
"a,you are changed",
b,
c
)

分析:(略)

結(jié)論:在這個例子里艰额,不僅修改了容器里的第一個元素的值,還往容器里新增加一個元素椒涯,根據(jù)打印結(jié)果可以知道悴晰,對NSMutableArray調(diào)用copy,是深拷貝逐工,但僅僅是容器的深拷貝铡溪,容器里的元素是指針拷貝。(也就是跟上一個例子效果是一樣的)

六泪喊、對深淺拷貝的總結(jié)
1棕硫、對于不可修改的非容器類對象(至少我驗證過NSString),copy是淺拷貝袒啼,mutableCopy是深拷貝;
2哈扮、對于可修改的非容器類對象(至少我驗證過NSMutableString),copy是深拷貝(但它返回的是一個不可修改的對象)蚓再,mutableCopy是深拷貝;
3滑肉、對于不可修改的容器類對象(至少我驗證過NSArray), copy是淺拷貝,mutableCopy是深拷貝(但不是完全意義上的深拷貝摘仅,只是容器的深拷貝靶庙,元素仍然是淺拷貝);
4、對于可修改的容器類對象(至少我驗證過NSMutableArray),copy是深拷貝(但不是完全意義上的深拷貝娃属,只是容器的深拷貝六荒,元素仍然是淺拷貝), mutableCopy是深拷貝(但不是完全意義上的深拷貝,只是容器的深拷貝矾端,元素仍然是淺拷貝);
5掏击、那么問題來了,對于容器類對象秩铆,如何實現(xiàn)完全意義上的深拷貝呢(容器和元素的都是深拷貝)砚亭?
答案是用歸檔

    NSArray* deepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
                              [NSKeyedArchiver archivedDataWithRootObject: array]];
(如果你不習(xí)慣什么淺拷貝和深拷貝,你可以將淺拷貝理解為沒有開辟新內(nèi)存殴玛,將深拷貝理解為開辟了新內(nèi)存)

七捅膘、自定義對象的copy和mutableCopy
ios中并不是所有的對象都支持copy,mutableCopy族阅,遵守NSCopying 協(xié)議的類可以發(fā)送copy消息篓跛,遵守NSMutableCopying 協(xié)議的類才可以發(fā)送mutableCopy消息。假如發(fā)送了一個沒有遵守上訴兩協(xié)議而發(fā)送 copy或者 mutableCopy,那么就會發(fā)生異常坦刀。但是默認(rèn)的ios類并沒有遵守這兩個協(xié)議愧沟。如果想自定義一下copy 那么就必須遵守NSCopying,并且實現(xiàn) copyWithZone: 方法,如果想自定義一下mutableCopy 那么就必須遵守NSMutableCopying,并且實現(xiàn) mutableCopyWithZone: 方法鲤遥。

參考資料
1沐寺、https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html
2、http://www.cnblogs.com/yswdarren/p/3611924.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盖奈,一起剝皮案震驚了整個濱河市混坞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖究孕,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啥酱,死亡現(xiàn)場離奇詭異,居然都是意外死亡厨诸,警方通過查閱死者的電腦和手機(jī)镶殷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來微酬,“玉大人绘趋,你說我怎么就攤上這事】殴埽” “怎么了陷遮?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長垦江。 經(jīng)常有香客問我帽馋,道長,這世上最難降的妖魔是什么疫粥? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任茬斧,我火速辦了婚禮,結(jié)果婚禮上梗逮,老公的妹妹穿的比我還像新娘项秉。我一直安慰自己,他們只是感情好慷彤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布娄蔼。 她就那樣靜靜地躺著,像睡著了一般底哗。 火紅的嫁衣襯著肌膚如雪岁诉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天跋选,我揣著相機(jī)與錄音涕癣,去河邊找鬼。 笑死前标,一個胖子當(dāng)著我的面吹牛坠韩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炼列,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼只搁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了俭尖?” 一聲冷哼從身側(cè)響起氢惋,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洞翩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后焰望,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骚亿,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年柿估,在試婚紗的時候發(fā)現(xiàn)自己被綠了循未。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡秫舌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绣檬,到底是詐尸還是另有隱情足陨,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布娇未,位于F島的核電站墨缘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏零抬。R本人自食惡果不足惜镊讼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望平夜。 院中可真熱鬧蝶棋,春花似錦、人聲如沸忽妒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽段直。三九已至吃溅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸯檬,已是汗流浹背决侈。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喧务,地道東北人赖歌。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像蹂楣,于是被迫代替她去往敵國和親俏站。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

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