對(duì)象、消息鹤耍、運(yùn)行期

對(duì)象 --- 在Objective-C等面向?qū)ο笳Z(yǔ)言編程時(shí)肉迫,“對(duì)象”(object)就是“基本構(gòu)造單元”,開發(fā)者可以通過對(duì)象來存儲(chǔ)并傳遞數(shù)據(jù)稿黄。
消息 --- 在對(duì)象之間傳遞數(shù)據(jù)并執(zhí)行任務(wù)的過程就叫做“消息傳遞”(Messaging)
運(yùn)行期 --- 當(dāng)應(yīng)用程序運(yùn)行起來以后喊衫,為其提供相關(guān)支持的代碼叫做“Objective-C運(yùn)行期環(huán)境”(Objectice-C runtime),它提供了一些使得對(duì)象之間能夠傳遞消息的重要函數(shù)杆怕,并且包含創(chuàng)建類實(shí)例所用的全部邏輯族购。

六、理解“屬性”這一概念

屬性(property)是Objective-C的一項(xiàng)特性陵珍,用戶封裝對(duì)象中的數(shù)據(jù)寝杖,iOS開發(fā)中最常用最方便的變量聲明方式,允許我們用點(diǎn)語(yǔ)法來訪問對(duì)象的實(shí)例變量互纯。實(shí)質(zhì)上類似如下

屬性 = 成員變量 + set方法 + get方法瑟幕。

屬性特質(zhì)

@property(nonatomic,readwrite,copy,setter=<name>) NSString *firstName;
  1. 原子性
    如果屬性具備noatomic特質(zhì),則不使用同步鎖留潦,iOS由于性能原因只盹,都是使用noatomic的,MacOS則多用atomic兔院,使用同步鎖殖卑。

  2. 讀寫權(quán)限
    擁有readwrite特質(zhì)的屬性擁有獲取方法getter和設(shè)置方法setter。
    擁有readonly特質(zhì)的屬性僅擁有獲取方法坊萝》趸可以在.h頭文件中對(duì)外公開為只讀屬性,然后再.m的class-continuation分類中將其重新定義為讀寫屬性十偶。

  3. 內(nèi)存管理語(yǔ)義
    屬性用于封裝數(shù)據(jù)菩鲜,而數(shù)據(jù)則要有“具體的所有權(quán)語(yǔ)義。內(nèi)存管理語(yǔ)義這個(gè)特質(zhì)僅會(huì)影響設(shè)置方法惦积。

    1. assign 設(shè)置方法只會(huì)執(zhí)行針對(duì)純量類型(非OC對(duì)象)的簡(jiǎn)單賦值操作接校,如CGFloat,NSInteger

    2. strong 定義了一種擁有關(guān)系荣刑。為這種屬性設(shè)置新值時(shí)馅笙,設(shè)置方法會(huì)先保留新值,并釋放舊值厉亏,然后再將新值設(shè)置上去董习。對(duì)象引用計(jì)數(shù)+1,功能等價(jià)于MRC里面的retain

    3. weak 非擁有關(guān)系爱只,為這種屬性設(shè)置新值時(shí)皿淋,既不保留新值,也不釋放舊值恬试。然而在屬性值所指對(duì)象遭到摧毀時(shí)窝趣,屬性值也會(huì)被清空為nil。weak是為打破循環(huán)引用而生的

    4. unsafe_unretained 類似weak训柴,但是區(qū)別于在當(dāng)目標(biāo)對(duì)象遭到摧毀時(shí)哑舒,屬性值不會(huì)自動(dòng)清空,這是不安全的幻馁。不建議使用洗鸵!

    5. copy 擁有關(guān)系,實(shí)質(zhì)上是設(shè)置為傳入對(duì)象的copy對(duì)象的指針。設(shè)置完后仗嗦,與傳入的對(duì)象無(wú)關(guān)聯(lián)膘滨。

        @property (nonatomic, copy) NSString *stringCopy  
        -(void)setStringCopy:(NSString *)stringCopy{
            [_stringCopy release];
            _stringCopy = [stringCopy copy];
        }
      

    當(dāng)屬性類型為NSString *時(shí),經(jīng)常用此特質(zhì)來保護(hù)其封裝性

  4. 方法名

     @property(nonatomic,getter=isOn)Bool on;
     //getter=<name> 指定獲取方法的方法名
     //setter=<name>,這種用法一般不常用稀拐,沒必要
    

特別注意:
如果想在其他方法里設(shè)置屬性值火邓,那么同樣要遵守屬性定義中所宣稱的語(yǔ)義。如下代碼:

@interface EOCPerson:NSManagedObject
@property(copy,readonly) NSString *firstName;
@property(copy,readonly) NSString *lastName;
-(id)initWithFirstName:(NSString *)firstName lastName:(NSString*)lastName;
@end

//.m文件中
-(id)initWithFirstName:(NSString *)firstName lastName:(NSString*)lastName{
    if((self = [super init])){
        _firstName = [firstName copy];
        _lastName = [lastName copy];
    }
}

在實(shí)現(xiàn)這個(gè)自定義初始化方法時(shí)德撬,一定要遵循屬性定義中宣稱的”copy“語(yǔ)義铲咨,因?yàn)閷傩远x就相當(dāng)于類和待設(shè)置的屬性值之間達(dá)成的契約。

七砰逻、在對(duì)象內(nèi)部盡量直接訪問實(shí)例變量

  1. "A:在對(duì)象內(nèi)部讀取數(shù)據(jù)時(shí)鸣驱,應(yīng)該直接通過實(shí)例變量來讀。B:寫入數(shù)據(jù)時(shí)蝠咆,則應(yīng)該通過屬性來寫踊东。" 這種方案的優(yōu)點(diǎn)是:既能提高讀取操作的速度,又能控制對(duì)屬性的寫入操作刚操,使得相關(guān)屬性的內(nèi)存管理語(yǔ)義得以貫徹闸翅。
  2. 針對(duì)1中A讀取內(nèi)部數(shù)據(jù)的例外情況是,在使用懶加載初始化技術(shù)配置某個(gè)數(shù)據(jù)的話菊霜,應(yīng)該通過屬性來讀取數(shù)據(jù)
  3. 針對(duì)1中B坚冀,寫入數(shù)據(jù)的例外情況是,初始化方法和dealloc方法中鉴逞,總是應(yīng)該直接通過實(shí)例變量來讀寫數(shù)據(jù)

八记某、理解"對(duì)象等同性"這一概念

根據(jù)“等同性”(equality)來比較對(duì)象是一個(gè)非常有用的功能司训。按照==操作符比較出來的結(jié)果未必是我們想要的,應(yīng)為該操作比較的是兩個(gè)指針本身液南,而不是其所指的對(duì)象壳猜。 我們應(yīng)該使用NSObject協(xié)議中聲明的"isEqual":方法來判斷兩個(gè)對(duì)象的等同性。

-(BOOL)isEqual:(id)object{
    if(self == object)
        return YES;
    if([self class] != [object class])
        return NO;
    
    EOCPerson *otherPerson = (EOCPerson *)object;
    if(![_firstName isEqualToString:otherPerson.firstName])
        return NO;
    if(![_lastName isEqualToString:otherPerson.lastName])
        return NO;
    if(_age != otherPerson.age)
        return NO;
    return YES;
}

-(NSUInterger)hash {
    NSUInteger firstNameHash = [_firstName hash];
    NSUInteger lastNameHash = [_lastName hash];
    NSUInteger ageHash = _age;
    return firstNameHash ^ lastNameHash ^ ageHash;
}
  1. 若想檢測(cè)對(duì)象的等同性滑凉,請(qǐng)?zhí)峁癷sEqual:”與hash方法
  2. 相同的對(duì)象必須具有相同的哈希碼统扳,但是兩個(gè)哈希碼相同的對(duì)象卻未必相同
  3. 不要盲目地逐個(gè)檢測(cè)每條屬性,而是應(yīng)該依照具體需求來定制檢測(cè)方案畅姊。
  4. 編寫hash方法時(shí)咒钟,應(yīng)該使用計(jì)算速度快而哈希碼碰撞幾率低的算法

九、以“類族模式”隱藏實(shí)現(xiàn)細(xì)節(jié)

創(chuàng)建如NSArray類族的子類時(shí)若未,需要遵守幾條規(guī)則:

  1. 子類應(yīng)該繼承自類族中的抽象基類
  2. 子類應(yīng)該定義自己的數(shù)據(jù)存儲(chǔ)方式
  3. 子類應(yīng)當(dāng)覆寫超類文檔中指明需要覆寫的方法

要點(diǎn):

  1. 類族模式可以把實(shí)現(xiàn)細(xì)節(jié)隱藏在一套簡(jiǎn)單的公共接口后面
  2. 系統(tǒng)框架中經(jīng)常使用類族
  3. 從類族的公共抽象基類中繼承子類時(shí)要當(dāng)心朱嘴,若有開發(fā)文檔,則應(yīng)首先閱讀

十陨瘩、在既有類中使用關(guān)聯(lián)對(duì)象存放自定義數(shù)據(jù)

“關(guān)聯(lián)對(duì)象”(Associated Object)是一個(gè)黑科技腕够,在某些類無(wú)法繼承出子類來存放額外信息時(shí),可以用關(guān)聯(lián)對(duì)象的方法舌劳,來增加鍵值對(duì)帚湘,達(dá)到給既定類存放額外信息的目的。

關(guān)聯(lián)類型 等效的@property屬性
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC nonatomic,retain
OBJC_ASSOCIATION_COPY_NONATOMIC nonatomic,copy
OBJC_ASSOCIATION_RETAIN retain
OBJC_ASSOCIATION_COPY copy

有以下方法管理關(guān)聯(lián)對(duì)象:

void objc_setAssociatedObject(id object,void *key,id value,objc_AssociationPolicy)  
//該方法以給定的鍵和策略為某對(duì)象設(shè)置關(guān)聯(lián)對(duì)象值

id objc_getAssociatedObject(id object, void *key)
//此方法根據(jù)給定的鍵從某對(duì)象中獲取相應(yīng)的關(guān)聯(lián)對(duì)象值

void objc_removeAssociatedObjects(id object)
//此方法移除指定對(duì)象的全部關(guān)聯(lián)對(duì)象  

特別注意: 設(shè)置關(guān)聯(lián)對(duì)象時(shí)用的鍵key是個(gè)不透明的指針甚淡。設(shè)置關(guān)聯(lián)對(duì)象值時(shí),通常使用靜態(tài)全局變量做鍵大诸。

staic void *EOCMyALertViewKey = "EOCMyAlertViewKey";  

//關(guān)聯(lián)對(duì)象,綁定block  
objc_setAssociatedObject(alertView,EOCMyAlertViewKey,block,OBJC_ASSOCIATION_COPY);   
//取值贯卦,取出block
void(^block)(NSInteger) = objc_getAssociatedObject(alertView,EOCMyAlertViewKey);
  1. 可以通過“關(guān)聯(lián)對(duì)象”機(jī)制來把兩個(gè)對(duì)象連起來
  2. 定義關(guān)聯(lián)對(duì)象時(shí)可以指定內(nèi)存管理語(yǔ)義资柔,用以模仿定義屬性時(shí)所采用的“擁有關(guān)系”與“非擁有關(guān)系”
  3. 只有在其他做法不可行時(shí)才應(yīng)選用 關(guān)聯(lián)對(duì)象,因?yàn)檫@種做法通常會(huì)引入難以查找的bug撵割,如循環(huán)引用

十一贿堰、理解objc_msgSend的作用

id returnValue = [someObject messageName:parameter];

someObject叫做"接收者"(receiver),messageName叫做“選擇子”(selector),選擇子與參數(shù)合起來稱為“消息”(message)啡彬。 編譯器看到此消息后羹与,將其轉(zhuǎn)換為一條標(biāo)準(zhǔn)的c語(yǔ)言函數(shù)調(diào)用,所調(diào)用的函數(shù)乃是消息傳遞機(jī)制中的核心函數(shù)庶灿,叫做objc_msgSend,其原型如下

void objc_msgSend(id self,SEL cmd, ...)

編譯器會(huì)把上面例子中的消息轉(zhuǎn)換為如下函數(shù):

id returnValue = objc_msgSend(someObject,@selector(messageName:),parameter);

objc_msgSend函數(shù)會(huì)依據(jù)接收者與選擇子的類型來調(diào)用適當(dāng)?shù)姆椒ㄗ莞椋瑸榱送瓿纱瞬僮鳎摲椒ㄐ枰诮邮照咚鶎俚念愔兴褜て洹胺椒斜怼保╨ist of methods)往踢,如果能找到與選擇子名稱相符的方法腾誉,就跳至其實(shí)現(xiàn)代碼。若是找不到,那就沿著繼承體系繼續(xù)向上查找利职,等找到合適的方法再跳轉(zhuǎn)趣效,如果最終還是找不到相符的方法,那就執(zhí)行消息轉(zhuǎn)發(fā)(message forwarding)操作猪贪。
objc_msgSend會(huì)將匹配結(jié)果緩存在“快速映射表”(fast map)里面英支,每個(gè)類都有這樣一塊緩存,若是稍后還向該類發(fā)送與選擇子相同的消息哮伟,那么執(zhí)行就會(huì)很快了。

Objective-C運(yùn)行環(huán)境中的另一些函數(shù)
  1. objc_msgSend_stret 如果待發(fā)送的消息要返回結(jié)構(gòu)體妄帘,就交由該函數(shù)處理
  2. objc_msgSend_fpret 如果消息返回的是浮點(diǎn)數(shù)楞黄,則交由此函數(shù)處理
  3. objc_msgSendSuper 如果要給超類發(fā)消息,例如[super message:parameter],那么就交由次函數(shù)處理

如果某函數(shù)的最后一項(xiàng)操作是調(diào)用另外一個(gè)函數(shù)抡驼,那么就可以運(yùn)用“尾調(diào)用技術(shù)”鬼廓,編譯器會(huì)生成調(diào)轉(zhuǎn)至另一函數(shù)所需的指令碼,而且不會(huì)向調(diào)用堆棧中推入新的棧幁致盟。

要點(diǎn):
  1. 消息由接收者碎税、選擇子以及參數(shù)構(gòu)成。給某對(duì)象“發(fā)送消息"馏锡,也就相當(dāng)于在該對(duì)象上"調(diào)用方法"
  2. 發(fā)給某對(duì)象的全部消息都要由"動(dòng)態(tài)消息派發(fā)系統(tǒng)"來處理雷蹂,該系統(tǒng)會(huì)查出對(duì)應(yīng)的方法,并執(zhí)行其代碼

十二杯道、理解消息轉(zhuǎn)發(fā)機(jī)制

當(dāng)對(duì)象接收無(wú)法解讀的消息后匪煌,就會(huì)啟動(dòng)"消息轉(zhuǎn)發(fā)"(message forwarding)機(jī)制,程序員可經(jīng)由此過程告訴對(duì)象應(yīng)該如何處理未知消息党巾。

消息轉(zhuǎn)發(fā)分為兩大階段:
  1. 第一階段先征詢接收者萎庭,所屬的類,看其是否能 動(dòng)態(tài)添加方法齿拂,以處理當(dāng)前這個(gè)"未知的選擇子"驳规,這叫做"動(dòng)態(tài)方法解析"(dynamic method resolution)
  2. 第二階段涉及"完整的消息轉(zhuǎn)發(fā)機(jī)制"(full forwarding mechanism),細(xì)分為兩步:首先,請(qǐng)接收者看看有沒有其他對(duì)象能處理這條消息署海,若有吗购,則運(yùn)行期系統(tǒng)會(huì)把消息轉(zhuǎn)個(gè)那個(gè)對(duì)象,消息轉(zhuǎn)發(fā)過程結(jié)束叹侄。其次,若沒有備援的接收者(replacement receiver),則啟動(dòng)完整的消息轉(zhuǎn)發(fā)機(jī)制巩搏,運(yùn)行期系統(tǒng)會(huì)把與消息有關(guān)的全部細(xì)節(jié)都封裝到NSInvocation對(duì)象中,再給接收者最后一次機(jī)會(huì)趾代,令其設(shè)法解決當(dāng)前未處理的這條消息
動(dòng)態(tài)方法解析

對(duì)象在收到無(wú)法解讀的消息后贯底,首先調(diào)用其所屬類的下列方法:

+(BOOL)resolveInstanceMethod:(SEL)selector

該方法的參數(shù)就是那個(gè)未知的選擇子,令其返回值為Boolean類型,<u>表示這個(gè)類是否能新增一個(gè)實(shí)例方法用于處理此選擇子</u>禽捆。在繼續(xù)往下執(zhí)行轉(zhuǎn)發(fā)機(jī)制之前笙什,本類有機(jī)會(huì)新增一個(gè)處理此選擇子的方法。假如未實(shí)現(xiàn)的方法不是實(shí)例方法而是類方法胚想,那么運(yùn)行期系統(tǒng)就會(huì)調(diào)用另一個(gè)方法琐凭,叫做"resolveClassMethod:" 。
<u>使用動(dòng)態(tài)方法解析的前提是:相關(guān)方法的實(shí)現(xiàn)代碼已經(jīng)寫好浊服,只等著運(yùn)行的時(shí)候動(dòng)態(tài)插在類里面就可以了</u>统屈。 此方案常用來實(shí)現(xiàn)@dynamic屬性,比方說牙躺,要訪問CoreData框架中NSManagedObjects對(duì)象的屬性時(shí)就可以這么做愁憔,因?yàn)閷?shí)現(xiàn)這些屬性所需的存取方法在編譯期就能確定。

id autoDictionaryGetter(id self,SEL _cmd);
void autoDictionarySetter(id self,SEL _cmd,id value);


+(BOOL)resolveInstanceMethod:(SEL)selector{
    NSString *selectorStirng = NSStringFormSelector(selector);
    if(/* selector is from a @dynamic property */){
        if([selectorString hasPrefix:@"set"]){
            class_addMethod(self,selector,(IMP)autoDictionarySetter,@"v@:@");
        }else{
            class_addMethod(self,selector,(IMP)autoDictionaryGetter,@"@@:"  
        }
        return YES;
    }
    return [super resolveInstanceMethod:selector];
}
備援接收者

當(dāng)前接收者還有第二次機(jī)會(huì)能處理未知的選擇子孽拷,在這一步中吨掌,運(yùn)行期系統(tǒng)會(huì)問它:能不能把這條消息轉(zhuǎn)給其他接收者來處理。

-(id)forwardingTargetForSelector:(SEL)selector

方法參數(shù)代表未知的選擇子脓恕,若當(dāng)前接收者能找到備援對(duì)象膜宋,則將其返回,否則就返回nil炼幔。
值得注意的是秋茫,我們無(wú)法操作經(jīng)由這一步所轉(zhuǎn)發(fā)的消息,若是想在發(fā)送給備援接收者之前修改消息內(nèi)容乃秀,那就得通過完整的消息轉(zhuǎn)發(fā)機(jī)制來做了学辱。

完整的消息轉(zhuǎn)發(fā)

如果轉(zhuǎn)發(fā)算法已經(jīng)來到這一步的話,那么唯一能做的就是啟用完整的消息轉(zhuǎn)發(fā)機(jī)制了环形。
首先創(chuàng)建NSInvocation對(duì)象策泣,把尚未處理的那條消息有關(guān)的全部細(xì)節(jié)都封于其中。此對(duì)象包含選擇子抬吟、目標(biāo)(target)及參數(shù)萨咕。在觸發(fā)NSInvocation對(duì)象時(shí),"消息派發(fā)系統(tǒng)"(message-dispatch system)將親自出馬火本,把消息指派給目標(biāo)對(duì)象危队。

-(void)forwardInvocation:(NSInvocation *)invocation
消息轉(zhuǎn)發(fā)全流程
要點(diǎn)
  1. 若對(duì)象無(wú)法響應(yīng)某個(gè)選擇子,則進(jìn)入消息轉(zhuǎn)發(fā)流程
  2. 通過運(yùn)行期的動(dòng)態(tài)方法解析功能钙畔,我們可以在需要用到某個(gè)方法時(shí)再將其加入類中
  3. 對(duì)象可以把其無(wú)法解讀的某些選擇子轉(zhuǎn)交給其他對(duì)象來處理
  4. 經(jīng)過上述兩步之后茫陆,如果還是沒有辦法處理選擇子,那就啟動(dòng)完整的消息轉(zhuǎn)發(fā)機(jī)制

十三擎析、用"方法調(diào)配技術(shù)"

類的方法列表會(huì)把選擇子的名稱映射到相關(guān)的方法實(shí)現(xiàn)之上簿盅,使得"動(dòng)態(tài)消息派發(fā)系統(tǒng)"能夠據(jù)此找到應(yīng)該調(diào)用的方法.這些方法均以函數(shù)指針的形式來表示,這種指針叫做IMP。其原型如下:

id (*IMP)(id,SEL,...)

可以通過以下c函數(shù)互換兩個(gè)方法實(shí)現(xiàn)

void method_exchangeImplementations(Method m1,Method m2)
//此函數(shù)的兩個(gè)參數(shù)表示待交換的兩個(gè)方法實(shí)現(xiàn)桨醋,而方法實(shí)現(xiàn)則可通過下列函數(shù)獲得
Method class_getInstanceMethod(Class class,SEL aSelector)
//此函數(shù)根據(jù)給定的選擇子從類中取出與之相關(guān)的方法

可以用自定義的類中方法交換某個(gè)目標(biāo)類中方法棚瘟,如下:

@implement NSString (EOCMyAdditions)
-(NSString *)eoc_myLowercaseString{
    NSString *lowercase = [self eoc_myLowercaseString];
    NSLog(@"%@ => %@",self,lowercase);
    return lowercase;
}
@end

Method originalMethod = class_getInstanceMethod([NSString class],@selector(lowercaseString)];
Method swappedMethod = class_getInstanceMethod([NSString class],@selector(eoc_myLowercaseString));
method_exchangeImplementations(originalMethod,swappedMethod);  

通過此方案,開發(fā)者可以為那些"完全不知道其具體實(shí)現(xiàn)的"黑盒方法增加日志記錄功能喜最,這非常有助于程序調(diào)試偎蘸,然后此做法只在調(diào)試的時(shí)候有用。若是濫用瞬内,會(huì)令代碼變得不易讀懂且難于維護(hù)迷雪。

要點(diǎn)
  1. 在運(yùn)行期,可以向類中新增或替換選擇子所對(duì)應(yīng)的方法實(shí)現(xiàn)
  2. 使用另一份實(shí)現(xiàn)來代替原有的方法實(shí)現(xiàn)虫蝶,這道工序叫做"方法調(diào)配"振乏,開發(fā)者常用此技術(shù)向原有實(shí)現(xiàn)中添加新功能
  3. 一般來說,只有調(diào)試程序的時(shí)候才需要在運(yùn)行期修改方法實(shí)現(xiàn)秉扑,這種方法不宜濫用

十四、理解"類對(duì)象"的用意

類型信息查詢: "在運(yùn)行期檢視對(duì)象類型"這一操作叫做類型信息查詢(introspection,內(nèi)实飨蕖)舟陆,這個(gè)強(qiáng)大而有用的特性內(nèi)置于Foundation框架的NSObject協(xié)議里,凡是由公共根類(common root class,即NSObject與NSProxy)繼承而來的對(duì)象都要遵從此協(xié)議耻矮。

Class對(duì)象也定義在運(yùn)行期程序庫(kù)的頭文件中:

typedef struct objc_class *Class;
struct objc_class{
    Class isa;
    Class superClass;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list **methodLists;
    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
}

其中super_class 指針確立了繼承關(guān)系秦躯,而isa指針描述了實(shí)例所屬的類。

"isMemberOfClass:"能夠判斷出對(duì)象是否為某個(gè)特定類的實(shí)例裆装;而"isKindOfClass:"則能夠判斷出是否為某類或其派生類的實(shí)例

要點(diǎn):
  1. 每個(gè)實(shí)例都有一個(gè)指向Class對(duì)象的指針isa踱承,用以表明其類型,而這些Class對(duì)象則構(gòu)成了類的繼承體系
  2. 如果對(duì)象類型無(wú)法在編譯期確定哨免,那么就應(yīng)該使用類型信息查詢方法來探知
  3. 盡量使用類型信息查詢方法來確定對(duì)象類型茎活,而不要直接比較類對(duì)象,因?yàn)槟承?duì)象可能實(shí)現(xiàn)了消息轉(zhuǎn)發(fā)功能
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末琢唾,一起剝皮案震驚了整個(gè)濱河市载荔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌采桃,老刑警劉巖懒熙,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異普办,居然都是意外死亡工扎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門衔蹲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肢娘,“玉大人,你說我怎么就攤上這事∈哒悖” “怎么了猪落?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)畴博。 經(jīng)常有香客問我笨忌,道長(zhǎng),這世上最難降的妖魔是什么俱病? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任忽孽,我火速辦了婚禮掠拳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己涣觉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布乌庶。 她就那樣靜靜地躺著怔毛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪促王。 梳的紋絲不亂的頭發(fā)上犀盟,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音蝇狼,去河邊找鬼阅畴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛迅耘,可吹牛的內(nèi)容都是我干的贱枣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼颤专,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼纽哥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起栖秕,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤昵仅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后累魔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摔笤,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年垦写,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吕世。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梯投,死狀恐怖命辖,靈堂內(nèi)的尸體忽然破棺而出况毅,到底是詐尸還是另有隱情,我是刑警寧澤尔艇,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布尔许,位于F島的核電站,受9級(jí)特大地震影響终娃,放射性物質(zhì)發(fā)生泄漏味廊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一棠耕、第九天 我趴在偏房一處隱蔽的房頂上張望余佛。 院中可真熱鬧,春花似錦窍荧、人聲如沸辉巡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)郊楣。三九已至,卻和暖如春瓤荔,著一層夾襖步出監(jiān)牢的瞬間净蚤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工茉贡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人者铜。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓腔丧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親作烟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子愉粤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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