Copy & MutableCopy

Copy & MutableCopy

前言

好久都沒(méi)寫東西了,除了平常的工作吧趣、學(xué)習(xí),過(guò)年的喜慶與忙碌....都是借口俯渤。

廢話不多說(shuō),讓我們進(jìn)行今天的話題,Copy 與 MutableCopy岖寞。


如何理解Copy

Question

為什么NSArray指巡、NSString、NSDictionary常用copy修飾?

最近有一些同學(xué)問(wèn)過(guò)我這個(gè)問(wèn)題,為了弄清這個(gè)問(wèn)題椭住,可能涉及到的東西有點(diǎn)多京郑,我會(huì)盡量用比較容易理解的例子和語(yǔ)言來(lái)解釋些举。當(dāng)然,實(shí)際編程中,可能會(huì)比我所舉的例子要復(fù)雜的多鸠信。

1.什么是 immutable 和 mutable 星立?
  • 在Cocoa的世界中,有一些類分為不可變 (immutable) 和可變 (mutable) 兩種版本辕坝。比如常見(jiàn)的 NSArray酱畅、 NSDictionary纺酸、 NSSet碎紊、NSString 等,對(duì)應(yīng)關(guān)系為(immutable->mutable):
    NSArray -> NSMutableArray
    NSString -> NSMutableString
    NSDictionary-> NSMutableDictionary

** 在設(shè)計(jì)類的時(shí)候,我們應(yīng)該充分運(yùn)用屬性來(lái)封裝數(shù)據(jù)顿膨,而如果沒(méi)有特殊要求,我們的屬性對(duì)外公開顾画,應(yīng)該聲明為只讀,避免在一個(gè)類的外部直接修改這個(gè)類的屬性,這樣可以為我們避免很多麻煩的事情末誓。 **

Example

** 我們都知道 NSSet 不會(huì)添加重復(fù)的數(shù)據(jù)喇澡。我們經(jīng)常用這個(gè)類來(lái)實(shí)現(xiàn)一些功能,例如一個(gè)人的朋友這樣的容器呕屎。那么尔当,我們來(lái)看看,下面這段程序如何來(lái)打破 NSSet 的這個(gè)特性畜号。 **

int main(int argc, const char * argv[]) {
 @autoreleasepool {
   NSMutableArray *array1 = [@[@1, @2] mutableCopy];
   NSMutableArray *array2 = [@[@1] mutableCopy];
   NSSet *set = [NSSet setWithObjects:array1, array2, nil];
   NSLog(@"Set: %@", set);
  }
  return 0;
}

** Log: **

2016-02-24 13:34:54.828 NSSet[1392:93361] Set: {(
      (
       1
   ),
       (
       1,
       2
   )
)}
Program ended with exit code: 0

** 很正常药蜻,沒(méi)什么問(wèn)題對(duì)吧贸典? 看我稍稍加一句代碼之后... **

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSMutableArray *array1 = [@[@1, @2] mutableCopy];
    NSMutableArray *array2 = [@[@1] mutableCopy];
    NSSet *set = [NSSet setWithObjects:array1, array2, nil];
    [array2 addObject:@2];
 NSLog(@"Set: %@", set);
  }
  return 0;
}

** Log: **

2016-02-24 13:38:11.294 NSSet[1409:94758] Set: {(
     (
     1,
     2
   ),
     (
     1,
     2
   )
)}
Program ended with exit code: 0

** 兩個(gè)一毛一樣的 NSMutableArray 就出現(xiàn)在一個(gè) NSSet容器中了廊驼,改變了 NSSet 的原義N鞫F谙骸!如果不信茂蚓,大家可以動(dòng)手試試御板。 **

** 說(shuō)一個(gè)常見(jiàn)的問(wèn)題吧淹朋,比如說(shuō)我們常寫的 CHRHomeViewController 有一個(gè) badge 屬性杈抢,這個(gè)屬性可能會(huì)在 Discovery Profile 等多個(gè)模塊中修改,如果我們直接改變這個(gè) badge 屬性歼捐,很可能就會(huì)出現(xiàn) Race Condition(靜態(tài)條件) 淘这。如果我們把 badge 屬性改成只讀(readonly) 钠怯,然后公開一個(gè) - updateBadge:(NSInteger)badge 方法晦炊,然后在本類的內(nèi)部用隊(duì)列或者其他技術(shù)刽锤,我們就可以比較容易的解決這個(gè)問(wèn)題并思。 **

** 說(shuō)了這么多宋彼,和我們最開始給出的問(wèn)題有什么關(guān)系么输涕? 關(guān)系還是有的莱坎,對(duì)于為什么 NSArray 等屬性經(jīng)常用 copy 來(lái)修飾碴卧,很大的一個(gè)方面就是為了保證住册,在set之后荧飞,我們得到的結(jié)果是 immutable 的類型叹阔。**

** 由于多態(tài)性忠荞,父類指針可以指向子類指針, 我們很可能寫出這樣的代碼: **

定義一個(gè)User類堂油,User有一個(gè)friends屬性
@interface CHRUser : NSObject

@property (nonatomic, strong) NSSet <CHRUser *> *friends;

@end

@implementation CHRUser

- (instancetype)init
{
  self = [super init];
  if (self) {
    _friends = [NSSet set];
  }
  return self;
}

@end

// 我們從服務(wù)器上拉取用戶chris的朋友們

int main(int argc, const char * argv[]) {
  @autoreleasepool {

    CHRUser *chris = [CHRUser new];

    NSMutableSet *friends = [NSMutableSet set];

    /* 從服務(wù)器拉取信息 ,解析得到這三個(gè)人是chris的朋友..... */
    CHRUser *mary = [CHRUser new];
    CHRUser *tom = [CHRUser new];
    CHRUser *bob = [CHRUser new];

    [friends addObject:mary];
    [friends addObject:tom];
    [friends addObject:bob];

    chris.friends = friends;

    NSLog(@"Chris' friends: %@", chris.friends);
    
    // 由于某些邏輯,在 friends 中又添加一個(gè)User
    CHRUser *babara = [CHRUser new];
    [friends addObject:babara];
    
    // 使用 friends 去做一些其他的事情
    NSLog(@"Chris' friends: %@", chris.friends);
  }
  return 0;
}

** 我們看看 Log 信息: **

2016-02-24 14:16:24.469 NSSet[1528:109524] Chris'   friends: {(
    <CHRUser: 0x100209ed0>,
    <CHRUser: 0x100209b80>,
    <CHRUser: 0x1002096b0>
)}
2016-02-24 14:16:24.469 NSSet[1528:109524] Chris'   friends: {(
    <CHRUser: 0x100500200>,
    <CHRUser: 0x100209b80>,
    <CHRUser: 0x100209ed0>,
    <CHRUser: 0x1002096b0>
)}
Program ended with exit code: 0

** Chris 的朋友莫名其妙的多了一個(gè)系宜,什么情況 盹牧? 因?yàn)?CHRUSer 的friends 屬性使用的是 strong 關(guān)鍵字修飾口柳,在 setFriends 之后有滑,只是一個(gè)引用指向了 friends 跃闹,所以如果后面的 friends 進(jìn)行增刪改等操作,那么 chris.friends 就會(huì)跟著變咯毛好。 **

** 我們把 friends 屬性改用 copy 修飾辣卒, 再看 Log: **

2016-02-24 14:27:12.002 NSSet[1565:114822] Chris'   friends: {(
    <CHRUser: 0x1001037f0>,
    <CHRUser: 0x100102f20>,
    <CHRUser: 0x1001038c0>
)}
2016-02-24 14:27:12.003 NSSet[1565:114822] Chris'   friends: {(
    <CHRUser: 0x1001037f0>,
    <CHRUser: 0x100102f20>,
    <CHRUser: 0x1001038c0>
)}
Program ended with exit code: 0

** 嗯,這通常就是我們想要的結(jié)果了睛榄, NSDictionary荣茫、 NSString 等道理類似〕⊙ィ可是為什么會(huì)這樣呢啡莉? **
** 在 Cocoa 的世界中,因?yàn)橹T如 NSArray 對(duì)應(yīng)有 immutable 和 mutable 兩種版本,所以 copy 操作就分成了 copy 和 mutableCopy 兩種復(fù)制方式哮兰。其復(fù)制前后結(jié)果如下: **

  1. copy 前后的類型

NSArray copy -> NSArray
NSMutableArray copy -> NSArray
NSString copy -> NSString
NSMutableString copy -> NSString
.....


  1. mutableCopy 前后的類型

NSArray mutableCopy -> NSMutableArray
NSMutableArray mutableCopy -> NSMutableArray
NSString mutableCopy -> NSMutableString
NSMutableString mutableCopy -> NSMutableString
......

** 可以看出膏秫,經(jīng)過(guò) copy 操作后,得到的總是 immutable 類型, 經(jīng)過(guò) mutableCopy 操作后婿斥, 得到的總是 mutable 類型活鹰。 那么這兩個(gè)操作到底做了什么呢? 代碼看一下。 **

  1. 對(duì) immutable 類進(jìn)行 copy 和 mutableCopy 操作
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            CHRUser *user = [CHRUser new];
NSArray *array = @[user];

            NSArray *copiedArray = [array copy];
            NSMutableArray *mutableCopiedArray = [array mutableCopy];
        
            // 拷貝前
            NSLog(@"Before copy : Class:%@, Address: %p, Content: %@, ContentObject Address: %p",
      NSStringFromClass([array class]),
      array,
      array,
      array.firstObject);
      
            // copy 之后
            NSLog(@"After copy : Class:%@, Address: %p, Content: %@, ContentObject Address: %p",
      NSStringFromClass([copiedArray class]),
      copiedArray,
      copiedArray,
      copiedArray.firstObject);
        
            // mutableCopy 之后
            NSLog(@"After mutableCopy : Class:%@, Address: %p, Content: %@, ContentObject Address: %p",
      NSStringFromClass([mutableCopiedArray class]),
      mutableCopiedArray,
      mutableCopiedArray,
      mutableCopiedArray.firstObject);
        }
        return 0;
    }

** Log: **

    2016-02-24 15:15:00.600 NSSet[1764:137701] Before copy : Class:__NSArrayI, Address: 0x1001038e0, Content: (
    "<CHRUser: 0x100102470>"
    ), ContentObject Address: 0x100102470
    2016-02-24 15:15:00.601 NSSet[1764:137701] After copy : Class:__NSArrayI, Address: 0x1001038e0, Content: (
    "<CHRUser: 0x100102470>"
    ), ContentObject Address: 0x100102470
    2016-02-24 15:15:00.602 NSSet[1764:137701] After mutableCopy : Class:__NSArrayM, Address: 0x100103a60, Content: (
    "<CHRUser: 0x100102470>"
    ), ContentObject Address: 0x100102470
    Program ended with exit code: 0

** 可以看出遍希,對(duì) immtable 類進(jìn)行 copy 、 mutableCopy 得到的結(jié)果是不一樣得别厘, mutableCopy 之后我們得到了一個(gè) NSArray 的可變版本,并且內(nèi)存地址與原始的 array 不同,說(shuō)明對(duì) immutable 類進(jìn)行 mutableCopy 得到的結(jié)果進(jìn)行了內(nèi)容拷貝颈畸,但是其容器內(nèi)部的數(shù)據(jù)并沒(méi)有拷貝內(nèi)容(地址沒(méi)有變化)徙缴,也就是說(shuō),拷貝了一個(gè) 糊余; 而對(duì) immutable 類進(jìn)行 copy 操作,與原始的 array 是一毛一樣, 也就是我們常說(shuō)的,拷貝了一份指針句柠。**

  1. 對(duì) mutable 類進(jìn)行 copy 和 mutableCopy 操作

     int main(int argc, const char * argv[]) {
       @autoreleasepool {
         CHRUser *user = [CHRUser new];
         NSMutableArray *mutableArray = [NSMutableArray arrayWithObject:user];
    
         NSArray *copiedArray = [mutableArray copy];
         NSMutableArray *mutableCopiedArray = [mutableArray mutableCopy];
         
         // 拷貝前
         NSLog(@"Before copy : Class:%@, Address: %p, Content: %@, ContentObject Address: %p",
       NSStringFromClass([mutableArray class]),
       mutableArray,
       mutableArray,
       mutableArray.firstObject);
       
         // copy 之后
         NSLog(@"After copy : Class:%@, Address: %p, Content: %@, ContentObject Address: %p",
       NSStringFromClass([copiedArray class]),
       copiedArray,
       copiedArray,
       copiedArray.firstObject);
    
         // mutableCopy 之后
         NSLog(@"After mutableCopy : Class:%@, Address: %p, Content: %@, ContentObject Address: %p",
       NSStringFromClass([mutableCopiedArray class]),
       mutableCopiedArray,
       mutableCopiedArray,
       mutableCopiedArray.firstObject);
      }
       return 0;
     }
    

** 我們?cè)賮?lái)看下 Log **

    2016-02-24 15:21:59.657 NSSet[1814:141214] Before copy : Class:__NSArrayM, Address: 0x100509bc0, Content: (
    "<CHRUser: 0x100506dd0>"
    ), ContentObject Address: 0x100506dd0
    2016-02-24 15:21:59.658 NSSet[1814:141214] After copy : Class:__NSArrayI, Address: 0x100507450, Content: (
    "<CHRUser: 0x100506dd0>"
    ), ContentObject Address: 0x100506dd0
    2016-02-24 15:21:59.658 NSSet[1814:141214] After mutableCopy : Class:__NSArrayM, Address: 0x100509bf0, Content: (
    "<CHRUser: 0x100506dd0>"
    ), ContentObject Address: 0x100506dd0
    Program ended with exit code: 0

** 我們發(fā)現(xiàn),對(duì)于一個(gè) mutable 類型的對(duì)象來(lái)說(shuō),不論進(jìn)行的是 copy 還是 mutableCopy 操作,其地址 Address 都不一樣, 而其容器中的內(nèi)容不變挠锥。則蓖宦,對(duì)一個(gè) mutable 類型的對(duì)象進(jìn)行 copy 或者是 mutableCopy 睬关,都拷貝了一個(gè)殼丐箩,而容器內(nèi)的數(shù)據(jù)不會(huì)進(jìn)行拷貝內(nèi)容的操作涎嚼。 **

** 所以說(shuō)立哑,我們經(jīng)常對(duì)外開放的屬性都是 immutable 的产喉,但因?yàn)槎鄳B(tài)性姐帚,總有可能寫出諸如 **

self.xxArray = xxMutableArray

** 這樣的代碼,程序可能會(huì)發(fā)生難以查明的 bug 。給維護(hù)帶來(lái)災(zāi)難。也有的時(shí)候柔纵,有人會(huì)問(wèn)你搁料, 一個(gè) NSMutableArray 使用 copy 修飾會(huì)發(fā)生什么昭伸, 經(jīng)過(guò)上面的講解夹供, NSMutableArray copy 后得到的是一個(gè) NSArray 類型的對(duì)象匪凉, 但是因?yàn)槁暶鞯氖?NSMutableArray , 所以我們調(diào)用 addObject: 等 API 時(shí)积瞒, Xcode 并不會(huì)給我們警告叮喳,但是運(yùn)行就會(huì)在 調(diào)用 addObject: 等 API 處奔潰(unrecognized selector sent to xxx)。 **

** 還有就是缰贝,我們要對(duì)自身編寫的有可變版本的類同時(shí)實(shí)現(xiàn)兩個(gè)協(xié)議來(lái)進(jìn)行拷貝操作馍悟, NSCopying 和 NSMutableCopying 協(xié)議, 并在 **

  • (id)copyWithZone:(NSZone *)zone;
  • (id)mutableCopyWithZone:(NSZone *)zone;

** 兩個(gè)方法分別返回不可變與可變版本剩晴,以供正常使用锣咒。 **

淺拷貝 VS 深拷貝

======

這里純屬擴(kuò)充下知識(shí)哈,會(huì)的同學(xué)別吐槽...

什么是淺拷貝呢?

** 我們?cè)趯?duì) immutable 類型的對(duì)象進(jìn)行 copy 時(shí)宠哄,發(fā)現(xiàn)拷貝前后容器的地址不變壹将,這種情況就叫做淺拷貝了嗤攻。只拷貝一份指針毛嫉,這個(gè)時(shí)候改變?cè)瓟?shù)據(jù)之后,淺拷貝的數(shù)據(jù)會(huì)跟著變化妇菱,因?yàn)榈刂废嗤铩?**

什么是又是深拷貝呢承粤?

** 深拷貝在我來(lái)看有一些不同的情況,比如說(shuō)上面在對(duì) immutable 類型的對(duì)象進(jìn)行 mutableCopy 的時(shí)候闯团,容器的地址變了辛臊,但是容器內(nèi)容沒(méi)變,這也算是深拷貝房交,不過(guò)只是拷貝了一個(gè)殼彻舰,如果改變其中的內(nèi)容,那么拷貝后的容器的內(nèi)容也跟著變化候味,這種拷貝我稱之為 非完全深拷貝(自己起的名字刃唤,別噴,哎呀白群,大家別噴...)尚胞。 示例代碼如下:**

我們?cè)谶@里創(chuàng)建兩個(gè)類,方便觀察帜慢。一個(gè)是 CHRUser 類笼裳,有一個(gè) name 讀寫屬性, 和一個(gè) dogs 的只讀屬性粱玲, 在這個(gè)類的內(nèi)部存儲(chǔ)著可變的 internalDogs 的讀寫屬性躬柬,存儲(chǔ)收養(yǎng)的狗狗們; CHRDog 類只有一個(gè)簡(jiǎn)單的 name 屬性抽减。 我們來(lái)看看如何實(shí)現(xiàn) copy:

  • CHRUser

      @class CHRDog;
    
      @interface CHRUser : NSObject
    
      @property (nonatomic, copy) NSString *name;
      @property (nonatomic, copy, readonly) NSSet <CHRDog *> *dogs;
    
      - (void)adoptDog:(CHRDog *)dog;
    
      @end
    
      #import "CHRUser.h"
      
      #import "CHRDog.h"
    
      @interface CHRUser ()
    
      @property (nonatomic, strong, readwrite) NSMutableSet <CHRDog *> *internalDogs;
    
      @end
    
      @implementation CHRUser
    
      - (instancetype)init
      {
        self = [super init];
        if (self) {
          _internalDogs = [NSMutableSet set];
        }
        return self;
      }
    
      - (NSSet<CHRUser *> *)friends
      {
        return [_internalDogs copy];
      }
    
      - (void)adoptDog:(CHRDog *)dog
      {
        [_internalDogs addObject:dog];
      }
    
      - (NSString *)description
      {
        return [NSString stringWithFormat:@"Address: %p\n Name: %@\n InternalDogs: %@",
        self,
        _name,
        _internalDogs];
          }
    
      #pragma mark - NSCopying
      - (id)copyWithZone:(NSZone *)zone
      {
        CHRUser *copy = [[CHRUser allocWithZone:zone] init];
        copy.name = [_name copy];
        copy.internalDogs = [_internalDogs mutableCopy];
        return copy;
      }
    
      @end
    
  • CHRDog

      @interface CHRDog : NSObject
    
      @property (nonatomic, copy) NSString *name;
    
      @end
    
      @implementation CHRDog
      @end
    
  • main

      int main(int argc, const char * argv[]) {
        @autoreleasepool {
          CHRDog *dog = [CHRDog new];
          dog.name = @"A Dog";
    
          CHRUser *user = [CHRUser new];
          user.name = @"Chris";
          [user adoptDog:dog];
          CHRUser *copy = [user copy];
    
          CHRDog *anotherDog = [CHRDog new];
          anotherDog.name = @"Another";
          [user adoptDog:anotherDog];
    
          NSLog(@"%@", user);
          NSLog(@"%@", copy);
        }
        return 0;
      }
    
  • Log

      2016-02-24 18:51:43.102 NSSet[3794:250903] Address: 0x100109880
       Name: Chris
       InternalDogs: {(
          <CHRDog: 0x100100100>,
          <CHRDog: 0x1001098d0>
      )}
      2016-02-24 18:51:43.103 NSSet[3794:250903] Address: 0x10010bf70
       Name: Chris
       InternalDogs: {(
          <CHRDog: 0x1001098d0>
      )}
      Program ended with exit code: 0
    

** 可以看到允青, copy 前后,內(nèi)部的變量地址相同胯甩,而且原 User 收養(yǎng)第二只狗狗的后昧廷, 對(duì)于 copy 復(fù)本沒(méi)有影響。但是如果我改變了 internalDogs 的第一個(gè) dog 的話偎箫,copy 復(fù)本的 internalDogs 還是會(huì)受到影響(這里我們用到了木柬, mutable 類型 mutableCopy 后,拷貝了一層殼淹办,還有對(duì)外公開只讀的 dogs 眉枕, 而在內(nèi)部做可變存儲(chǔ)的一些方式,解決Race Condition(靜態(tài)條件)的方式并未給出,方式有很多速挑,大家可以討論下)谤牡。 **

** 這種結(jié)果有的時(shí)候就是我們想要的,但有的時(shí)候我們希望拷貝出來(lái)的副本與原始復(fù)本完全互相不影響姥宝,那么我們就需要用到 完全深拷貝(別打翅萤,別打.... 別走,喂腊满,別走啊套么, 你還是打我吧
:( 。 **

  • 完全深拷貝

** 還有一種情況是碳蛋,不只是拷貝了一個(gè)殼胚泌,連內(nèi)容也全部拷貝過(guò)來(lái),這種我稱之為 完全深拷貝肃弟,就是將一個(gè)對(duì)象的容器屬性玷室、變量等一邊拷貝,并且將容器中的每一內(nèi)容都進(jìn)行拷貝笤受。還是上述代碼穷缤,只需要改變一下User NSCopying 協(xié)議的方法實(shí)現(xiàn),在讓 CHRDog 實(shí)現(xiàn)NSCopying 協(xié)議感论,我們就可以做到完全深拷貝绅项。 修改如下: **

  • 修改后的 CHRDog.m

      @implementation CHRDog
    
      - (id)copyWithZone:(NSZone *)zone
      {
        CHRDog *copy = [[CHRDog allocWithZone:zone] init];
        copy.name = _name;
        return copy;
      }
    
      @end
    
  • 修改后的 CHRUser - copyWithZone:

      - (id)copyWithZone:(NSZone *)zone
      {
        CHRUser *copy = [[CHRUser allocWithZone:zone] init];
        copy.name = [_name copy];
        copy.internalDogs = [[NSMutableSet alloc] initWithSet:_internalDogs copyItems:YES];
        return copy;
      }
    
  • Log

      2016-02-24 18:58:32.352 NSSet[3832:253844] Address: 0x1001021e0
       Name: Chris
       InternalDogs: {(
          <CHRDog: 0x1001024e0>,
          <CHRDog: 0x1001003c0>
      )}
      2016-02-24 18:58:32.352 NSSet[3832:253844] Address: 0x1001023b0
       Name: Chris
       InternalDogs: {(
          <CHRDog: 0x1001032e0>
      )}
      Program ended with exit code: 0
    

** 我們看到,修改之后的 Log 文件比肄,原始的 user 與其復(fù)本 copy 中的 internalDogs 的地址都不一樣快耿, 這樣,無(wú)論我們?cè)趺葱薷脑嫉幕蛘邚?fù)本芳绩,他們都不會(huì)互相影響到了掀亥。 當(dāng)然,在真正的項(xiàng)目中遇到的問(wèn)題會(huì)比這復(fù)雜的多妥色,不過(guò)只要我們掌握好原理搪花,那么就容易解決了。 **

尾聲

** 好久沒(méi)有寫新的東西了嘹害,今天花了一天的時(shí)間撮竿,由于時(shí)間的關(guān)系,后面寫的可能有一些匆忙(中間還有人問(wèn)了一些問(wèn)題笔呀,導(dǎo)致思路斷檔...)幢踏,不過(guò)只要大家覺(jué)得能夠?qū)W到一些東西,或者我們共同討論 许师,升華一下知識(shí)房蝉,我都覺(jué)得無(wú)比的開心和榮耀僚匆。 **

** 文章中如果有不對(duì)的地方,請(qǐng)指出搭幻,我會(huì)盡可能快的修改咧擂,歡迎 大家來(lái)找茬 :)。 **

我是Chris檀蹋, 一個(gè) 90 后的 iOSer松申。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市续扔,隨后出現(xiàn)的幾起案子攻臀,更是在濱河造成了極大的恐慌焕数,老刑警劉巖纱昧,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異堡赔,居然都是意外死亡识脆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門善已,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)灼捂,“玉大人,你說(shuō)我怎么就攤上這事换团∠こ恚” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵艘包,是天一觀的道長(zhǎng)的猛。 經(jīng)常有香客問(wèn)我,道長(zhǎng)想虎,這世上最難降的妖魔是什么卦尊? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮舌厨,結(jié)果婚禮上岂却,老公的妹妹穿的比我還像新娘。我一直安慰自己裙椭,他們只是感情好躏哩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著揉燃,像睡著了一般扫尺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上你雌,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天器联,我揣著相機(jī)與錄音二汛,去河邊找鬼。 笑死拨拓,一個(gè)胖子當(dāng)著我的面吹牛肴颊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渣磷,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼婿着,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了醋界?” 一聲冷哼從身側(cè)響起竟宋,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎形纺,沒(méi)想到半個(gè)月后丘侠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逐样,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年蜗字,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脂新。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挪捕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出争便,到底是詐尸還是另有隱情级零,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布滞乙,位于F島的核電站奏纪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏酷宵。R本人自食惡果不足惜亥贸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一浇垦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧男韧,春花似錦此虑、人聲如沸朦前。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赴背。三九已至凰荚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缆毁,已是汗流浹背胳徽。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留往核,地道東北人嚷节。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓衩婚,卻偏偏與公主長(zhǎng)得像效斑,于是被迫代替她去往敵國(guó)和親缓屠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • 1. 屬性中copy與strong特性的區(qū)別 在開始學(xué)習(xí)淺復(fù)制(Shallow Copy)热幔、深復(fù)制(Deep Co...
    pro648閱讀 1,721評(píng)論 2 16
  • 寫在前面 Objective-C中的copy相關(guān)內(nèi)容比我想象中要豐富多了。 NSCopying和NSMutable...
    梅西121閱讀 1,693評(píng)論 0 0
  • 《那就這樣吧》 26歲的我 卻再也不能把這首歌聽(tīng)完 便化作 《驚鴻一面》 柳下聞謠琴起舞和一曲 仿若映當(dāng)年翩若驚鴻...
    蒙山小道閱讀 99評(píng)論 0 0
  • 1.日均運(yùn)動(dòng)大于10km(步行+快走+跑步) 2.記錄每天的家庭流水,月底統(tǒng)計(jì) 3.寫成功场勤、做計(jì)劃、多思考 4.每...
    資深小夏閱讀 159評(píng)論 0 1
  • 在公路上發(fā)現(xiàn)花兒都開好了格遭。 鮮艷的顏色留瞳,讓司機(jī)不再那么視覺(jué)疲勞拒迅,減少交通事故她倘,維護(hù)環(huán)境生態(tài)平衡。 這家店面太有復(fù)古...
    畫心邪師閱讀 333評(píng)論 2 3