jspatch使用技巧

1. require

在使用Objective-C類之前需要調(diào)用require('className’):

require('UIView')varview=UIView.alloc().init()

可以用逗號(hào),分隔荷并,一次性導(dǎo)入多個(gè)類:

require('UIView, UIColor')varview=UIView.alloc().init()varred=UIColor.redColor()

或者直接在使用時(shí)才調(diào)用require():

require('UIView').alloc().init()

2. 調(diào)用OC方法

調(diào)用類方法

varredColor=UIColor.redColor();

調(diào)用實(shí)例方法

varview=UIView.alloc().init();view.setNeedsLayout();

參數(shù)傳遞

跟在OC一樣傳遞參數(shù):

var view = UIView.alloc().init();

var superView = UIView.alloc().init()

superView.addSubview(view)

Property

獲取/修改 Property 等于調(diào)用這個(gè) Property 的 getter / setter 方法,獲取時(shí)記得加():

view.setBackgroundColor(redColor);varbgColor=view.backgroundColor();

方法名轉(zhuǎn)換

多參數(shù)方法名使用_分隔:

varindexPath=require('NSIndexPath').indexPathForRow_inSection(0,1);

若原 OC 方法名里包含下劃線_青扔,在 JS 使用雙下劃線__代替:

// Obj-C: [JPObject _privateMethod];JPObject.__privateMethod()

3. defineClass

API

defineClass(classDeclaration, [properties,] instanceMethods, classMethods)

@paramclassDeclaration: 字符串源织,類名/父類名和Protocol

@paramproperties: 新增property,字符串?dāng)?shù)組微猖,可省略

@paraminstanceMethods: 要添加或覆蓋的實(shí)例方法

@paramclassMethods: 要添加或覆蓋的類方法

覆蓋方法

1.在 defineClass 里定義 OC 已存在的方法即可覆蓋谈息,方法名規(guī)則與調(diào)用規(guī)則一樣,使用_分隔:

// OC@implementationJPTestObject- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath*)indexPath{}@end

// JSdefineClass("JPTableViewController", {tableView_didSelectRowAtIndexPath:function(tableView,indexPath) {...},})

2.使用雙下劃線__代表原OC方法名里的下劃線_:

// OC@implementationJPTableViewController- (NSArray*)_dataSource{}@end

// JSdefineClass("JPTableViewController", {__dataSource:function() {? },})

3.在方法名前加ORIG即可調(diào)用未覆蓋前的 OC 原方法:

// OC@implementationJPTableViewController- (void)viewDidLoad{}@end

// JSdefineClass("JPTableViewController", {viewDidLoad:function() {self.ORIGviewDidLoad();? },})

覆蓋類方法

defineClass()第三個(gè)參數(shù)就是要添加或覆蓋的類方法凛剥,規(guī)則與上述覆蓋實(shí)例方法一致:

// OC@implementationJPTestObject+ (void)shareInstance{}@end

// JSdefineClass("JPTableViewController", {//實(shí)例方法}, {//類方法shareInstance:function() {...},})

覆蓋 Category 方法

覆蓋 Category 方法與覆蓋普通方法一樣:

@implementationUIView(custom)- (void)methodA{}+ (void)clsMethodB{}@end

defineClass('UIView', {methodA:function() {? }}, {clsMethodB:function() {? }});

Super

使用self.super()接口代表 super 關(guān)鍵字侠仇,調(diào)用 super 方法:

// JSdefineClass("JPTableViewController", {viewDidLoad:function() {self.super().viewDidLoad();? }})

Property

獲取/修改 OC 定義的 Property

用調(diào)用 getter / setter 的方式獲取/修改已在 OC 定義的 Property:

// OC@interfaceJPTableViewController@property(nonatomic)NSArray*data;@property(nonatomic)NSString*shareURL;@property(nonatomic)NSString*shareTitle;@end@implementationJPTableViewController@end

// JSdefineClass("JPTableViewController", {viewDidLoad:function() {vardata=self.data();//get property valueself.setData(data.toJS().push("JSPatch"));//set property valuevarsel=self;self.bridge().registerHandler_handler('h5ToNativeShareDialog',block('NSDictionary *',function(data,responseCallback) {sel.setShareURL(data.objectForKey('url'));sel.setShareTitle(data.objectForKey('title'));? ? }));})

動(dòng)態(tài)新增 Property

可以在defineClass()第二個(gè)參數(shù)為類新增 property,格式為字符串?dāng)?shù)組犁珠,使用時(shí)與 OC property 接口一致:

defineClass("JPTableViewController", ['data','totalCount'], {init:function() {? ? self=self.super().init()self.setData(["a","b"])//添加新的 Property (id data)self.setTotalCount(2)returnself? },viewDidLoad:function() {vardata=self.data()//獲取 Property 值vartotalCount=self.totalCount()? },})

私有成員變量

使用valueForKey()和setValue_forKey()獲取/修改私有成員變量:

// OC@implementationJPTableViewController{NSArray*_data;}@end

// JSdefineClass("JPTableViewController", {viewDidLoad:function() {vardata=self.valueForKey("_data")//get member variablesself.setValue_forKey(["JSPatch"],"_data")//set member variables},})

添加新方法

可以給一個(gè)類隨意添加 OC 未定義的方法逻炊,但所有的參數(shù)類型都是id:

// OC@implementationJPTableViewController- (void)viewDidLoad{NSString* data = [selfdataAtIndex:@(1)];NSLog(@"%@", data);//output: Patch}@end

// JSvardata=["JS","Patch"]defineClass("JPTableViewController", {dataAtIndex:function(idx) {returnidx

若新增的方法屬于 Protocol 里的接口互亮,需要在 defineClass 的類聲明參數(shù)里指明實(shí)現(xiàn)的 Protocol,詳見(jiàn)下文嗅骄。

Protocol

可以在定義時(shí)讓一個(gè)類實(shí)現(xiàn)某些 Protocol 接口胳挎,寫法跟 OC 一樣:

defineClass("JPViewController: UIViewController", {})

這樣做的作用是,當(dāng)添加 Protocol 里定義的方法溺森,而類里沒(méi)有實(shí)現(xiàn)的方法時(shí)慕爬,參數(shù)類型不再全是id,而是自動(dòng)轉(zhuǎn)為 Protocol 里定義的類型:

@protocolUIAlertViewDelegate...- (void)alertView:(UIAlertView *)alertViewclickedButtonAtIndex:(NSInteger)buttonIndex;...@end

defineClass("JPViewController: UIViewController ", {viewDidAppear:function(animated) {varalertView=require('UIAlertView')? ? ? .alloc()? ? ? .initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles("Alert",self.dataSource().objectAtIndex(indexPath.row()),? ? ? ? self,"OK",null)alertView.show()? }alertView_clickedButtonAtIndex:function(alertView,buttonIndex) {console.log('clicked index'+buttonIndex)? }})

4. 特殊類型

Struct

JSPatch原生支持 CGRect / CGPoint / CGSize / NSRange 這四個(gè) struct 類型屏积,用 JS 對(duì)象表示:

// Obj-CUIView *view = [[UIViewalloc]initWithFrame:CGRectMake(20,20,100,100)];[viewsetCenter:CGPointMake(10,10)];[viewsizeThatFits:CGSizeMake(100,100)];CGFloatx = view.frame.origin.x;NSRangerange =NSMakeRange(0,1);

// JSvarview=UIView.alloc().initWithFrame({x:20, y:20, width:100, height:100})view.setCenter({x:10, y:10})view.sizeThatFits({width:100, height:100})varx=view.frame().xvarrange={location:0, length:1}

其他 Struct 類型的支持請(qǐng)參照添加 struct 類型支持

Selector

在JS使用字符串代表 Selector:

//Obj-C[selfperformSelector:@selector(viewWillAppear:)withObject:@(YES)];

//JSself.performSelector_withObject("viewWillAppear:",1)

nil

JS 上的null和undefined都代表 OC 的nil医窿,如果要表示NSNull, 用nsnull代替,如果要表示NULL, 也用null代替:

//Obj-C@implemention JPTestObject+ (BOOL)testNull(NSNull*null) {return[nullisKindOfClass:[NSNullclass]]}@end

//JSrequire('JPTestObject').testNull(nsnull)//return 1require('JPTestObject').testNull(null)//return 0

在JS里面判斷是否為空要判斷false:

varurl="";varrawData=NSData.dataWithContentsOfURL(NSURL.URLWithString(url));if(rawData!=null) {}//這樣判斷是錯(cuò)誤的應(yīng)該如下判斷:if(!rawData){}在JSPatch.js源碼里_formatOCToJS方法對(duì)undefined,null,isNil轉(zhuǎn)換成了false炊林。

5. NSArray / NSString / NSDictionary

NSArray / NSString / NSDictionary 不會(huì)自動(dòng)轉(zhuǎn)成對(duì)應(yīng)的JS類型姥卢,像普通 NSObject 一樣使用它們:

//Obj-C@implementationJPObject+ (NSArray*)data{return@[[NSMutableStringstringWithString:@"JS"]]}+ (NSMutableDictionary*)dict{return[[NSMutableDictionaryalloc]init];}@end

// JSrequire('JPObject')varocStr=JPObject.data().objectAtIndex(0)ocStr.appendString("Patch")vardict=JPObject.dict()dict.setObject_forKey(ocStr,'name')console.log(dict.objectForKey('name'))//output: JSPatch

如果要把 NSArray / NSString / NSDictionary 轉(zhuǎn)為對(duì)應(yīng)的 JS 類型,使用.toJS()接口:

// JSvardata=require('JPObject').data().toJS()//data instanceof Array === truedata.push("Patch")vardict=JPObject.dict()dict.setObject_forKey(data.join(''),'name')dict=dict.toJS()console.log(dict['name'])//output: JSPatch

6. Block

block 傳遞

當(dāng)要把 JS 函數(shù)作為 block 參數(shù)給 OC時(shí)渣聚,需要先使用block(paramTypes, function)接口包裝:

// Obj-C@implementationJPObject+ (void)request:(void(^)(NSString*content,BOOLsuccess))callback{callback(@"I'm content",YES);}@end

// JSrequire('JPObject').request(block("NSString *, BOOL",function(ctn,succ) {if(succ)log(ctn)//output: I'm content}))

這里 block 里的參數(shù)類型用字符串表示独榴,寫上這個(gè) block 各個(gè)參數(shù)的類型,用逗號(hào)分隔奕枝。NSObject 對(duì)象如NSString *,NSArray *等可以用id表示棺榔,但 block 對(duì)象要用NSBlock*表示。

從 OC 返回給 JS 的 block 會(huì)自動(dòng)轉(zhuǎn)為 JS function隘道,直接調(diào)用即可:

// Obj-C@implementationJPObjecttypedefvoid(^JSBlock)(NSDictionary*dict);+ (JSBlock)genBlock{NSString*ctn =@"JSPatch";? JSBlock block = ^(NSDictionary*dict) {NSLog(@"I'm%@, version:%@", ctn, dict[@"v"])? };returnblock;}+ (void)execBlock:(JSBlock)blk{}@end

// JSvarblk=require('JPObject').genBlock();blk({v:"0.0.1"});//output: I'm JSPatch, version: 0.0.1

若要把這個(gè)從 OC 傳過(guò)來(lái)的 block 再傳回給 OC症歇,同樣需要再用block()包裝,因?yàn)檫@里blk已經(jīng)是一個(gè)普通的 JS function谭梗,跟我們上面定義的 JS function 沒(méi)有區(qū)別:

// JSvarblk=require('JPObject').genBlock();blk({v:"0.0.1"});//output: I'm JSPatch, version: 0.0.1require('JPObject').execBlock(block("id", blk));

總結(jié):JS 沒(méi)有 block 類型的變量忘晤,OC 的 block 對(duì)象傳到 JS 會(huì)變成 JS function,所有要從 JS 傳 block 給 OC 都需要用block()接口包裝激捏。

block 里使用 self 變量

在 block 里無(wú)法使用self變量设塔,需要在進(jìn)入 block 之前使用臨時(shí)變量保存它:

defineClass("JPViewController", {viewDidLoad:function() {varslf=self;require("JPTestObject").callBlock(block(function(){//`self` is not available here, use `slf` instead.slf.doSomething();? ? });? }}

限制

從 JS 傳 block 到 OC,有兩個(gè)限制:

A. block 參數(shù)個(gè)數(shù)最多支持6個(gè)缩幸。(若需要支持更多壹置,可以修改源碼)

B. block 參數(shù)類型不能是double/NSBlock/struct類型。

另外不支持 JS 封裝的 block 傳到 OC 再傳回 JS 去調(diào)用(原因見(jiàn)issue #155):

- (void)callBlock:(void(^)(NSString*str))block {}

defineClass('JPTestObject', {run:function() {self.callBlock(block('NSString*',function(str) {console.log(str);? ? ? ? }));? ? },callBlock:function(blk) {//blk 這個(gè) block 是上面的 run 函數(shù)里 JS 傳到 OC 再傳過(guò)來(lái)的表谊,無(wú)法調(diào)用。blk("test block");? ? ? }});

7. __weak / __strong

可以在 JS 通過(guò)__weak()聲明一個(gè) weak 變量盖喷,主要用于避免循環(huán)引用爆办。

例如我們?cè)?OC 里為了避免 block 導(dǎo)致的循環(huán)引用,經(jīng)常這樣寫:

- (void)test {? ? __weakidweakSelf = self;? ? [selfsetCompleteBlock:^(){? ? ? ? [weakSelfblabla];? ? }]}

在 JS 對(duì)應(yīng)的可以這樣寫:

varweakSelf=__weak(self)self.setCompleteBlock(block(function(){weakSelf.blabla();}))

若要在使用 weakSelf 時(shí)把它變成 strong 變量课梳,可以用__strong()接口:

varweakSelf=__weak(self)self.setCompleteBlock(block(function(){varstrongSelf=__strong(weakSelf)strongSelf.blabla();}))

8. GCD

使用dispatch_after()dispatch_async_main()dispatch_sync_main()dispatch_async_global_queue()接口調(diào)用GCD方法:

// Obj-Cdispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{// do something});dispatch_async(dispatch_get_main_queue(), ^{// do something});

// JSdispatch_after(1.0,function(){// do something})dispatch_async_main(function(){// do something})dispatch_sync_main(function(){// do something})dispatch_async_global_queue(function(){// do something})

9. 傳遞id*參數(shù)

如果你需要傳遞id*參數(shù)距辆,像NSURLConnection里的這個(gè)接口里的NSError **:

+ (NSData*)sendSynchronousRequest:(NSURLRequest*)request returningResponse:(NSURLResponse**)response error:(NSError**)error;

這里傳入的是一個(gè)指向 NSObject 對(duì)象的指針余佃,在方法里可以修改這個(gè)指針指向的對(duì)象,調(diào)用后外部可以拿到新指向的對(duì)象跨算,對(duì)于這樣的參數(shù)爆土,首先需要引入JPMemory 擴(kuò)展,然后按以下步驟進(jìn)行傳遞和獲戎畈稀:

使用malloc(sizeof(id))創(chuàng)建一個(gè)指針

把指針作為參數(shù)傳給方法

方法調(diào)用完步势,使用pval()拿到指針新指向的對(duì)象

使用完后調(diào)用releaseTmpObj()釋放這個(gè)對(duì)象

使用free()釋放指針

舉個(gè)例子:

//OC- (void)testPointer:(NSError**)error {NSError*err = [[NSErroralloc]initWithDomain:@"com.jspatch"code:42userInfo:nil];? ? *error = err;}

//JS//malloc() pval() free() is provided by JPMemory extensionrequire('JPEngine').addExtensions(['JPMemory'])varpError=malloc(sizeof("id"))self.testPointer(pError)varerror=pval(pError)if(!error) {console.log("success")}else{console.log(error)}releaseTmpObj(pError)free(pError)

若反過(guò)來(lái)你想在 JS 替換上述-testPointer:方法,構(gòu)建NSError對(duì)象賦給傳進(jìn)來(lái)的指針背犯,可以這樣寫:

defineClass('JPClassName', {testPointer:function(error){vartmp=require('NSError').errorWithDomain_code_userInfo("test",1,null);varnewErrorPointer=getPointer(tmp)memcpy(error, newErrorPointer,sizeof('id'))? ? });

10. 常量坏瘩、枚舉、宏漠魏、全局變量

常量/枚舉

Objective-C 里的常量/枚舉不能直接在 JS 上使用倔矾,可以直接在 JS 上用具體值代替:

//OC[btnaddTarget:selfaction:@selector(handleBtn)forControlEvents:UIControlEventTouchUpInside];

//UIControlEventTouchUpInside的值是1<<6btn.addTarget_action_forControlEvents(self,"handleBtn",1<<6);

或者在 JS 上重新定義同名的全局變量:

//jsvarUIControlEventTouchUpInside=1<<6;btn.addTarget_action_forControlEvents(self,"handleBtn", UIControlEventTouchUpInside);

有些常量字符串,需要在 OC 用 NSLog 打出看看它的值是什么:

//OC[[NSAttributedStringalloc].initWithString:@"str"attributes:@{NSForegroundColorAttributeName: [UIColorredColor]];

上面代碼中NSForegroundColorAttributeName是一個(gè)靜態(tài)字符串常量柱锹,源碼里看不出它的值哪自,可以先用 NSLog 打出它的值再直接寫在 JS 上:

//OCNSLog(@"%@",NSForegroundColorAttributeName)//output 'NSColor'

NSAttributedString.alloc().initWithString_attributes("無(wú)效啊", {'NSColor': UIColor.redColor()});

獲取宏值

Objective-C 里的宏同樣不能直接在 JS 上使用。若定義的宏是一個(gè)值禁熏,可以在 JS 定義同樣的全局變量代替壤巷,若定義的宏是程序,可以在JS展開(kāi)宏:

#defineTABBAR_HEIGHT40#defineSCREEN_WIDTH[[UIScreenmainScreen]bounds].size.height[viewsetWidth:SCREEN_WIDTHheight:TABBAR_HEIGHT];

//JSview.setWidth_height(UIScreen.mainScreen().bounds().height,40);

若宏的值是某些在底層才能獲取到的值匹层,例如CGFLOAT_MIN隙笆,可以通過(guò)在某個(gè)類或?qū)嵗椒ɡ飳⑺祷兀蛘哂锰砑訑U(kuò)展的方式提供支持:

@implementationJPMacroSupport+ (void)main:(JSContext *)context{? context[@"CGFLOAT_MIN"] = ^CGFloat() {returnCGFLOAT_MIN;? }}@end

require('JPEngine').addExtensions(['JPMacroSupport'])varfloatMin=CGFLOAT_MIN();

修改宏值

JSPatch 不支持修改宏的值升筏,若要修改撑柔,需要替換所有使用到這個(gè)宏的方法。例如:

#defineVIEW_HEIGHT40@implementationJPMethodDemo+ (void)func{? UIView *view = [[UIViewalloc]initWithFrame:CGRectMake(0,0,100, VIEW_HEIGHT)];? ...}@end

//JSvarVIEW_HEIGHT_NEW=20;defineClass('JPMethodDemo', {func:function() {varview=UIView.alloc().initWithFrame({x:0, y:0, width:100, height:VIEW_HEIGHT_NEW});...}});

全局變量

在類里定義的static全局變量無(wú)法在 JS 上獲取到您访,若要在 JS 拿到這個(gè)變量铅忿,需要在 OC 有類方法或?qū)嵗椒ò阉祷兀?/p>

staticNSString*name;@implementationJPTestObject+ (NSString*)name{returnname;}@end

varname=JPTestObject.name()//拿到全局變量值

11. Swift

使用defineClass()覆蓋Swift類時(shí),類名應(yīng)為項(xiàng)目名.原類名灵汪,例如項(xiàng)目 demo 里用 Swift 定義了 ViewController 類檀训,在 JS 覆蓋這個(gè)類方法時(shí)要這樣寫:

defineClass('demo.ViewController', {})

對(duì)于調(diào)用已在 swift 定義好的類,也是一樣:

require('demo.ViewController')

需要注意幾點(diǎn):

只支持調(diào)用繼承自NSObject的 Swift 類

繼承自NSObject的 Swift 類享言,其繼承自父類的方法和屬性可以在 JS 調(diào)用峻凫,其他自定義方法和屬性同樣需要加dynamic關(guān)鍵字才行。

若方法的參數(shù)/屬性類型為 Swift 特有(如 Character / Tuple)览露,則此方法和屬性無(wú)法通過(guò) JS 調(diào)用荧琼。

Swift 項(xiàng)目在 JSPatch 新增類與 OC 無(wú)異,可以正常使用。

12. 加載動(dòng)態(tài)庫(kù)

對(duì)于iOS內(nèi)置的動(dòng)態(tài)庫(kù)命锄,若原 APP 里沒(méi)有加載堰乔,可以通過(guò)以下方式動(dòng)態(tài)加載,以加載SafariServices.framework為例:

var bundle = NSBundle.bundleWithPath("/System/Library/Frameworks/SafariServices.framework");

bundle.load();

加載后就可以使用SafariServices.framework了脐恩。

13. 調(diào)試

可以使用console.log()打印一個(gè)對(duì)象镐侯,作用相當(dāng)于NSLog(),會(huì)直接在 XCode 控制臺(tái)打出驶冒。

console.log()支持任意參數(shù)苟翻,但不支持像 NSLog 這樣NSLog(@"num:%f", 1.0)的拼接:

var view = UIView.alloc().init();

var str = "test";

var num = 1;

console.log(view, str, num)

console.log(str + num);? //直接在JS拼接字符串

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市只怎,隨后出現(xiàn)的幾起案子袜瞬,更是在濱河造成了極大的恐慌,老刑警劉巖身堡,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邓尤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡贴谎,警方通過(guò)查閱死者的電腦和手機(jī)汞扎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)擅这,“玉大人澈魄,你說(shuō)我怎么就攤上這事≈亵幔” “怎么了痹扇?”我有些...
    開(kāi)封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)溯香。 經(jīng)常有香客問(wèn)我鲫构,道長(zhǎng),這世上最難降的妖魔是什么玫坛? 我笑而不...
    開(kāi)封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任结笨,我火速辦了婚禮,結(jié)果婚禮上湿镀,老公的妹妹穿的比我還像新娘炕吸。我一直安慰自己,他們只是感情好勉痴,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布赫模。 她就那樣靜靜地躺著,像睡著了一般蒸矛。 火紅的嫁衣襯著肌膚如雪嘴瓤。 梳的紋絲不亂的頭發(fā)上扫外,一...
    開(kāi)封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天莉钙,我揣著相機(jī)與錄音廓脆,去河邊找鬼。 笑死磁玉,一個(gè)胖子當(dāng)著我的面吹牛停忿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚊伞,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼席赂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了时迫?” 一聲冷哼從身側(cè)響起颅停,我...
    開(kāi)封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掠拳,沒(méi)想到半個(gè)月后癞揉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溺欧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年喊熟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姐刁。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芥牌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出聂使,到底是詐尸還是另有隱情壁拉,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布柏靶,位于F島的核電站弃理,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宿礁。R本人自食惡果不足惜案铺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梆靖。 院中可真熱鬧控汉,春花似錦、人聲如沸返吻。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)测僵。三九已至街佑,卻和暖如春谢翎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沐旨。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工森逮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人磁携。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓褒侧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谊迄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子闷供,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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