談?wù)劀\拷貝和深拷貝

為什么回頭再看這些基礎(chǔ)知識呢智什,因為覺得好記性不如爛筆頭榨乎。以前知其然不知所以然的東西,為了實現(xiàn)功能而實現(xiàn)功能而沒有時間歸納總結(jié)负饲,覺得還是用文章的形式記錄下來很好堤魁,好了,閑話不多說返十,回歸正題妥泉,當(dāng)然同類文章比比皆是,但自己寫一寫跟看一看的感覺會不太一樣洞坑,畢竟也算是自己的體會之一吧盲链。

拷貝,就是復(fù)制對象迟杂」粽矗拷貝分兩種,分別是淺拷貝排拷、深拷貝侧漓。

  • 淺拷貝

    不會產(chǎn)生新的對象,指針指向的地址沒有改變监氢,也就是沒有創(chuàng)建新的內(nèi)存空間布蔗,即復(fù)制指針。

  • 深拷貝

    會產(chǎn)生新的對象浪腐,指針指向的地址會改變纵揍,也就是創(chuàng)建了新的內(nèi)存空間,即內(nèi)容拷貝牛欢。

那么copy和mutableCopy有什么區(qū)別呢

  • copy

    不可變拷貝骡男,對于不可變的Foundation框架的常見類,是不創(chuàng)建新內(nèi)存空間的傍睹,對于可變的Foundation框架的常見類以及自定義的對象隔盛,會開辟一份內(nèi)存空間給新對象犹菱。新對象都是不可變的。

  • mutableCopy

    可變拷貝吮炕,其拷貝過程就是在內(nèi)存中重新開辟一塊區(qū)域腊脱,將對象復(fù)制一份放到這個區(qū)域。新對象是可以改變的龙亲,而且新對象的改變對原對象是沒有影響的陕凹。

我們來以例子說明:

一、NSString

不可變字符串

 NSString *str = @"test";
 NSString *copyStr = [string copy];
 NSMutableString *mutableCopyStr = [string mutableCopy];
 
 NSLog(@"str:%@,%p",str,str);
 NSLog(@"copyStr:%@,%p,%d",copyStr,copyStr,copyStr == str);
 NSLog(@"mutableCopyStr:%@,%p,%d",muCopyStr,mutableCopyStr,mutableCopyStr == str);
 
打遇:

str:test,0x10145b098

copyStr:test,0x10145b098,1

muCopyStr:test,0x7feb9355aed0,0

可變字符串

NSMutableString  *str = [[NSMutableString alloc]initWithString:@"test"];
NSString *copyStr = [str copy];
NSMutableString *mutableCopyStr = [str mutableCopy];

NSLog(@"str:%@,%p",str,str);
NSLog(@"copyStr:%@,%p,%d",copyStr,copyStr,copyStr == str);
NSLog(@"mutableCopyStr:%@,%p,%d",mutableCopyStr,mutableCopyStr,mutableCopyStr == str);
打佣虐摇:

str:test,0x7fbd90f0f640

copyStr:test,0xa000000747365744,0
 
muCopyStr:test,0x7fbd90f0be70,0

由此可見,對于不可變字符串拂盯,copy不會產(chǎn)生新的對象佑女,mutableCopy卻是會產(chǎn)生新的對象;對于可變字符串谈竿,copy和mutableCopy都是產(chǎn)生新的對象团驱,只是copy產(chǎn)生一個不可變的新對象,而mutableCopy產(chǎn)生一個可變的新對象空凸。

我們再來看看這個例子

NSString  *str =@"test"; 
NSString *copyStr = [str copy];
NSMutableString *mutableCopyStr = [str mutableCopy];
   
str = @"test0";
//重新給Str賦值嚎花,實際重新給Str開辟一個內(nèi)存空間,因此這一操作后實際這三個對象都是不一樣的
    
NSLog(@"str:%@,%p",str,str);
NSLog(@"copyStr:%@,%p,%d",copyStr,copyStr,copyStr == str);
NSLog(@"mutableCopyStr:%@,%p,%d",mutableCopyStr,mutableCopyStr,mutableCopyStr == str);
str:test0,0x10745e218
copyStr:test,0x10745e098,0
mutableCopyStr:test,0x7fa15beab330,0
二呀洲、NSArray

NSArray和NSstring都是Foundation類的一種紊选,所以情況都是一樣

不可變數(shù)組

NSArray  *arr =@[@"test"];
NSArray *copyArr = [arr copy];
NSMutableArray *mutableCopyArr = [arr mutableCopy];

NSLog(@"arr:%@,%p",arr,arr);
NSLog(@"copyArr:%@,%p,%d",copyArr,copyArr,copyArr == arr);
NSLog(@"mutableCopyArr:%@,%p,%d",mutableCopyArr,mutableCopyArr,mutableCopyArr == arr);
打印:
arr:(
    test
),0x7fdc4161bbd0

copyArr:(
    test
),0x7fdc4161bbd0,1

mutableCopyArr:(
    test
),0x7fdc4161b160,0

可變數(shù)組

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",nil];
NSMutableArray *copyArr = [arr copy];
    
[copyArr removeLastObject];
Xcode崩潰

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI removeLastObject]: unrecognized selector sent to instance 0x7fa2da614120'

Foundation框架常用的類有:NSNumber两嘴、NSString丛楚、NSArray、NSDictionary憔辫、NSMutableArray趣些、NSMutableDictionay、NSMutableString等copy產(chǎn)生的對象時不可變的贰您,mutableCopy產(chǎn)生的對象時可變的


NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",nil];
NSArray *copyArr = [arr copy];
  
NSMutableArray *mutableCopyArr = [arr mutableCopy];
    
arr[0] = @"0";
    
NSLog(@"arr:%@,%p",arr,arr);
NSLog(@"copyArr:%@,%p,%d",copyArr,copyArr,copyArr == arr);
NSLog(@"mutableCopyArr:%@,%p,%d",mutableCopyArr,mutableCopyArr,mutableCopyArr == arr);
    
[mutableCopyArr addObject:@"hello"];
     
NSLog(@"mutableCopyArr:%@,%p,%d",mutableCopyArr,mutableCopyArr,mutableCopyArr == arr);

打踊灯健:
arr:(
    0,
    2,
    3
),0x7f94fbe12550

copyArr:(
    1,
    2,
    3
),0x7ffc12611020,0

 mutableCopyArr:(
    1,
    2,
    3
),0x7f94fbe79f80,0

對于Foundation框架的常見類:

  • 不可變:(NS*)

    • copy,淺拷貝锦亦,不產(chǎn)生新對象

    • mutableCopy舶替,深拷貝,產(chǎn)生新可變對象

  • 可變:(NSMutable*)

    • copy杠园,深拷貝顾瞪,產(chǎn)生新不可變對象,

    • mutableCopy,深拷貝陈醒,產(chǎn)生新可變對象

另外提一點惕橙,我們比較提倡多用字面量語法創(chuàng)建這些類

例如:

NSMutableArray *arr = [@[] mutableCopy];

NSMutableDictionary *dict = [@{} mutableCopy];
三、自定義對象

先建一個Person類

@interface Person : NSObject
@property (nonatomic, copy)NSString *pid;
@property (nonatomic, copy)NSString *name;
@end

//初始化Person對象
Person *p = [[Person alloc] init];
p.name = @"joe";
p.pid = @"10";

Person *copyP = [p copy];

Xcode運行的話钉跷,不出意外肯定會報錯

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person copyWithZone:]: unrecognized selector sent to instance 0x7ff643641780'

原因就是沒有實現(xiàn)copyWithZone:這個方法

@protocol NSCopying
- (id)copyWithZone:(nullable NSZone *)zone;
@end

@protocol NSMutableCopying
- (id)mutableCopyWithZone:(nullable NSZone *)zone;
@end

command+左鍵可以得知這個方法是NSCopying里的協(xié)議方法弥鹦,那么Person要先遵循NSCopying方法

@interface Person : NSObject<NSCopying>
@property (nonatomic, copy)NSString *pid;
@property (nonatomic, copy)NSString *name;
@end

@implementation Person
- (id)copyWithZone:(NSZone *)zone{
    
    return @"test";
}

//初始化一個Person對象

Person *p = [[Person alloc] init];
p.name = @"joe";
p.pid = @"10";

Person *copyP = [p copy];

NSLog(@"p = %p copyP = %p", p, copyP);
p = 0x7fab996acf50 copyP = 0x10ab5c088

可以得出copyWithZone:(NSZone *)zone 實際為新對象重新分配了內(nèi)存空間,由于返回是一個字符串爷辙,所以copyP實際是一個NSString類的對象

@implementation Person
- (id)copyWithZone:(NSZone *)zone{
   //已給p分配了zone彬坏,就無需再alloc內(nèi)存空間
   // Person *p = [[Person alloc]init];
   //如果Person類會被繼承,那么將Person allocWithZone 改為[self class]  allocWithZone:
   // Person *p = [[Person allocWithZone:zone]init];
    Person *p = [[[self class] allocWithZone:zone] init];
    p.name = self.name;
    p.pid = self.pid;
    return p;
}

//初始化Person對象
Person *p = [[Person alloc] init];
p.name = @"joe";
p.pid = @"10";
 
Person *copyP = [p copy];

NSLog(@"p = %p copyP = %p", p, copyP);
NSLog(@"name = %@,  pid = %@", copyP.name, copyP.pid);
    
NSLog(@"p.name地址:%p膝晾,copyP.name地址:%p",p.name,copyP.name);

p = 0x7fbfcb40e470 copyP = 0x7fbfcb418330

name = joe,  pid = 10

p.name地址:0x10489d2a8栓始,copyP.name地址:0x10489d2a8

copyWithZone為淺拷貝,自定義對象重寫該方法玷犹,當(dāng)進(jìn)行copy時為新對象分配了一個新的內(nèi)存地址混滔,mutableCopyWithZone為深拷貝洒疚,也會為新對象分配一個新的內(nèi)存地址歹颓,所以當(dāng)[p copy]時需要遵循 NSCopying 協(xié)議并重寫copyWithZone方法,當(dāng)[p mutableCopy]時需要遵循NSMutableCopying并重寫mutableCopyWithZone油湖,兩者的寫法也是一樣的巍扛。

- (id)mutableCopyWithZone:(NSZone *)zone{
   Person *p = [[[self class] allocWithZone:zone] init];
   p.name = self.name;
   p.pid = self.pid;
   return p;
}

當(dāng)子類繼承父類時,子類也會遵循父類的NSCopying協(xié)議乏德,這時可以不用再在子類里重寫copyWithZone方法撤奸。
但是有個缺陷,雖然我們可以在父類里使用runtime遍歷所有成員屬性列表喊括,然后賦值胧瓜,但其父類的屬性還是賦值不到。

@interface Person : NSObject<NSCopying>
@property (nonatomic, copy)NSString *pid;
@property (nonatomic, copy)NSString *name;
@end

@implementation Person
- (id)copyWithZone:(NSZone *)zone{
   id obj = [[[self class]allocWithZone:zone]init];
   unsigned int outCount;
   Ivar * ivars = class_copyIvarList([self class], &outCount);
   for (int i = 0; i < outCount; i ++) {
       Ivar ivar = ivars[i];
       NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)];
       id value = [self valueForKey:key];
       [obj setValue:value forKey:key];
    }
   free(ivars);
   return obj;
}

@interface Student : Person
@property (nonatomic, copy) NSString *age;
@end

//初始化Student對象
Student *s = [[Student alloc]init];
s.name = @"marry";
s.age = @"18";
    
Student *copyS = [s copy];
NSLog(@"s = %p copyS = %p", s, copyS);
NSLog(@"name = %@ age = %@", copyS.name, copyS.age);

打又J病:

s = 0x7fa83a608ce0 copyS = 0x7fa83a61a100

name = (null)  age = 18

這里需要遍歷到父類的成員變量

- (id)copyWithZone:(NSZone *)zone{
   id obj = [[[self class]allocWithZone:zone]init];
    void (^getIvarsBlock)(Class) = ^(Class c){
        unsigned int outCount;
        Ivar * ivars = class_copyIvarList(c, &outCount);
        for (int i = 0; i < outCount; i ++) {
            Ivar ivar = ivars[i];
            NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            id value = [self valueForKey:key];
            [obj setValue:value forKey:key];
            NSLog(@"copy-----%@",key);
         }
        free(ivars);
    };
    Class c = [self class];
    while (c) {
        getIvarsBlock(c);
        c = class_getSuperclass(c);
        NSLog(@"class---%@",c);
        if ( c == [NSObject class]) {
            break;
        }
    }
    return obj;
}

這時候再來看看屬性Strong和copy就容易理解了
例如
我們在Person類里再添加一條屬性

@interface Person : NSObject<NSCopying>
@property (nonatomic, copy)NSString *pid;
@property (nonatomic, copy)NSString *name;
@property (nonatomic, copy) NSMutableArray *arr;
@end

//初始化Person對象

 Person *p = [[Person alloc] init];
 p.name = @"joe";
 p.pid = @"10";
 NSMutableArray *arr =  [@[@"test"] mutableCopy];
 p.arr = arr;
    
 [arr addObject:@"hell0"];

 Person *copyP = [p copy];
    
    
NSLog(@"arr:%p府喳, p.arr:%@  %p,\n copyP.arr:%@ %p",arr,p.sign,p.arr,copyP.arr,copyP.arr);
arr:0x7fddea4358a0蘑拯,p.arr:(
    test
)钝满,0x7fddea43d0b0,

copyP.arr:(
    test
)申窘,0x7fddea43d0b0

@property 本質(zhì)是:ivar(實例變量)弯蚜、存取方法(access method = getter + setter)

當(dāng)用copy修飾時,self.arr實際實現(xiàn)這個setter方法

- (void)setArr:(NSMutableArray *)arr{
    _arr = [arr copy];
}
[p.arr addObject:@"hell0"];

必然會報錯誤
[__NSArrayI addObject:]: unrecognized selector sent to instance 0x7ff3b94ee1a0'

所以self.arr 仍是不可變的剃法,所以不要在@property添加可變屬性

那我們用strong修飾試試

@property (nonatomic, strong) NSMutableArray *arr;
//初始化Person對象

Person *p = [[Person alloc] init];
p.name = @"joe";
p.pid = @"10";
NSMutableArray *arr =  [@[@"test"] mutableCopy];
p.arr = arr;
    
[arr addObject:@"hell0"];

Person *copyP = [p copy];

NSLog(@"arr:%p碎捺, p.arr:%@ %p,\n copyP.arr:%@ %p",arr,p.sign,p.arr,copyP.arr,copyP.arr);
     
arr:0x7fbbf8503cc0,p.arr:(
    test,
    hell0
)收厨,0x7fbbf8503cc0悍引,

copyP.arr:(
    test,
    hell0
),0x7fbbf8503cc0

實際用當(dāng)用strong修飾時帽氓,self.arr實現(xiàn)這個setter方法

- (void)setArr:(NSMutableArray *)arr{
    _arr = arr
}

所以用strong修飾時趣斤,self.arr 為可變數(shù)組,地址沒有改變黎休,當(dāng)arr改變時浓领,self.arr也會改變。

上面我們也注意到势腮,copyWithZone: 產(chǎn)生的是淺復(fù)制联贩,所以這種方法只能產(chǎn)生第一層深復(fù)制,如果集合內(nèi)元素仍然是集合捎拯,則子集合內(nèi)元素不會被深復(fù)制泪幌,只對子集合內(nèi)元素指針進(jìn)行復(fù)制。

我們看看這個例子

NSMutableString * testStr = [NSMutableString stringWithString:@"test"];

NSArray *arr = @[testStr];
NSArray *copyArr = [arr copy];
NSMutableArray *mutableCopyArr = [arr mutableCopy];
NSArray *arr2 = [[NSArray alloc]initWithArray:arr copyItems:YES];
    
[testStr appendString:@" hello"];
    
 NSLog(@" arr.firstObject = %p, \n copyArr.firstObject= %p, \n mutableCopyArr.firstObject= %p, \n arr2.firstObject =%p",arr.firstObject, copyArr.firstObject, mutableCopyArr.firstObject, arr2.firstObject);

NSLog(@"arr %@, \n copyArr %@, \n mutableCopyArr %@, \n arr2 %@",arr, copyArr, mutableCopyArr, arr2);

打印:

arr.firstObject = 0x7fbfd27069a0, 
copyArr.firstObject = 0x7fbfd27069a0, 
mutableCopyArr.firstObject =  0x7fbfd27069a0, 
arr2.firstObject = 0xa000000747365744
 
arr (
    "test hello"
), 
 copyArr (
    "test hello"
), 
 mutableCopyArr (
    "test hello"
), 
 arr2 (
    test
)

使用initWithArray: copyItems:YES署照,同initWithDictionary copyItems:YES

只能深拷貝到第2層祸泪,如果還有更深層的,還是不能完全深拷貝

NSMutableString * testStr = [NSMutableString stringWithString:@"test"];
NSMutableArray *testArr = [NSMutableArray arrayWithObject:testStr];

NSArray *arr = @[testArr];
NSArray *copyArr = [arr copy];
NSMutableArray *mutableCopyArr = [arr mutableCopy];
NSArray *arr2 = [[NSArray alloc]initWithArray:arr copyItems:YES];
    
[testStr appendString:@" hello"];
    
NSLog(@" arr.firstObject = %p, \n copyArr.firstObject= %p, \n mutableCopyArr.firstObject =%p, \n arr2.firstObject =%p",arr.firstObject, copyArr.firstObject, mutableCopyArr.firstObject, arr2.firstObject);

NSLog(@"arr %@, \n copyArr %@, \n mutableCopyArr %@, \n arr2 %@",arr, copyArr, mutableCopyArr, arr2);

打咏ㄜ健:
arr.firstObject = 0x7fb50bf0cf60, 
copyArr.firstObject = 0x7fb50bf0cf60, 
mutableCopyArr.firstObject = 0x7fb50bf0cf60, 
arr2.firstObject = 0x7fb50bf002f0
 
arr (
        (
        "test hello"
    )
), 
 copyArr (
        (
        "test hello"
    )
), 
 mutableCopyArr (
        (
        "test hello"
    )
), 
 arr2 (
        (
        "test hello"
    )
)

想實現(xiàn)完全深復(fù)制没隘,應(yīng)使用歸檔解檔。使用歸檔和解檔需要遵循NSCoding協(xié)議禁荸。

NSMutableString * testStr = [NSMutableString stringWithString:@"test"];
NSMutableArray *testArr = [NSMutableArray arrayWithObject:testStr];
    
NSArray *arr = @[testArr];
NSArray *copyArr = [arr copy];
NSMutableArray *mutableCopyArr = [arr mutableCopy];
NSArray *arr2 = [[NSArray alloc]initWithArray:arr copyItems:YES];
    
 //完全深拷貝
    
NSArray *arr3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:arr]];
    
[testStr appendString:@" hello"];
    
id  firstObject1 = [arr firstObject][0];
id  firstObject2 = [copyArr firstObject][0];
id  firstObject3 = [mutableCopyArr firstObject][0];
id  firstObject4 = [arr2 firstObject][0];
id  firstObject5 = [arr3 firstObject][0];
    
NSLog(@" arr.firstObject.firstObject = %p, \n copyArr.firstObject.firstObject = %p, \n mutableCopyArr.firstObject.firstObject = %p, \n arr2.firstObject.firstObject = %p右蒲,arr3.firstObject.firstObject = %p",firstObject1, firstObject2, firstObject3, firstObject4,firstObject5);
 
NSLog(@"arr %@, \n copyArr %@, \n mutableCopyArr %@, \n arr2 %@,\n arr3 %@",arr, copyArr, mutableCopyArr,arr2,arr3);

打痈鲜臁:

arr.firstObject.firstObject = 0x7fd4d271e8d0, copyArr.firstObject.firstObject = 0x7fd4d271e8d0, 
mutableCopyArr.firstObject.firstObject = 0x7fd4d271e8d0, 
arr2.firstObject.firstObject = 0x7fd4d271e8d0瑰妄,
arr3.firstObject.firstObject = 0x7fd4d272b360
 
arr (
        (
        "test hello"
    )
), 
copyArr (
        (
        "test hello"
    )
), 
mutableCopyArr (
        (
        "test hello"
    )
), 
arr2 (
        (
        "test hello"
    )
),
arr3 (
        (
        test
    )
)

我們考慮深拷貝時映砖,如果集合的結(jié)構(gòu)元素不嵌套其他集合间坐,mutableCopy會復(fù)制所有內(nèi)容,當(dāng)集合元素還是集合啊央,就應(yīng)考慮歸檔解檔實現(xiàn)完全深拷貝眶诈。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瓜饥,隨后出現(xiàn)的幾起案子逝撬,更是在濱河造成了極大的恐慌,老刑警劉巖乓土,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宪潮,死亡現(xiàn)場離奇詭異溯警,居然都是意外死亡,警方通過查閱死者的電腦和手機狡相,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門梯轻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人尽棕,你說我怎么就攤上這事喳挑。” “怎么了滔悉?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵伊诵,是天一觀的道長。 經(jīng)常有香客問我回官,道長曹宴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任歉提,我火速辦了婚禮笛坦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苔巨。我一直安慰自己版扩,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布恋拷。 她就那樣靜靜地躺著资厉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔬顾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音,去河邊找鬼翎承。 笑死治拿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的涕蚤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烹骨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起材泄,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沮焕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拉宗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體峦树,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡辣辫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了魁巩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片急灭。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谷遂,靈堂內(nèi)的尸體忽然破棺而出葬馋,到底是詐尸還是另有隱情,我是刑警寧澤肾扰,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布点楼,位于F島的核電站,受9級特大地震影響白对,放射性物質(zhì)發(fā)生泄漏掠廓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一甩恼、第九天 我趴在偏房一處隱蔽的房頂上張望蟀瞧。 院中可真熱鬧,春花似錦条摸、人聲如沸悦污。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽切端。三九已至,卻和暖如春顷啼,著一層夾襖步出監(jiān)牢的瞬間踏枣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工钙蒙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留茵瀑,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓躬厌,卻偏偏與公主長得像马昨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扛施,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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