亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScriptCore 詳解

2019-11-09 18:07:41
字體:
來源:轉載
供稿:網友

本博客主要分以下幾個方面來介紹iOS中的javaScriptCore

JavascriptCore簡介JavaScriptCore中主要的類JSContextJSValueJSExportJSManagedValueJSVirtualMachineNative Code 和 JS 之間的互相調用Native Code 與UIWebView中的JS交互Native Code 與JS文件直接交互

JavaScriptCore簡介

JavaScriptCore背景

iOS中的JavaScriptCore.framework其實只是基于webkit(Safari的瀏覽器引擎)中以C/C++實現的JavaScriptCore的一個包裝,在iOS7中,Apple將其作為一個標準庫供開發者使用

JavaScriptCore主要功能

JavaScriptCore主要是對JS進行解析和提供執行環境。代碼是開源的,JavaScriptCore源碼JavaScriptCore可以讓我們脫離webview直接運行我們的jsJavaScriptCore提供一種動態局部升級和更新的邏輯,大大提高應用的可擴展性對手機內嵌web模式的新嘗試點,即通過Native+JS file的方式取代webview的方式

JavaScriptCore中主要的類

JSContext --- 在OC中創建JavaScript運行的上下文環境

- (instancetype)init; // 創建JSContext對象,獲得JavaScript運行的上下文環境 // 在特定的對象空間上創建JSContext對象,獲得JavaScript運行的上下文環境 - (instancetype)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine; // 運行一段js代碼,輸出結果為JSValue類型 - (JSValue *)evaluateScript:(NSString *)script; // iOS 8.0以后可以調用此方法 - (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL NS_AVAILABLE(10_10, 8_0); // 獲取當前正在運行的JavaScript上下文環境 + (JSContext *)currentContext; // 返回結果當前執行的js函數 function () { [native code] } ,iOS 8.0以后可以調用此方法 + (JSValue *)currentCallee NS_AVAILABLE(10_10, 8_0); // 返回結果當前方法的調用者[object Window] + (JSValue *)currentThis; // 返回結果為當前被調用方法的參數 + (NSArray *)currentArguments; // js的全局變量 [object Window] @PRoperty (readonly, strong) JSValue *globalObject;

JSValue --- JavaScript中的變量和方法,可以轉成OC數據類型,每個JSValue都和JSContext相關聯并且強引用context

@textblock Objective-C type | JavaScript type --------------------+--------------------- nil | undefined NSNull | null NSString | string NSNumber | number, boolean NSDictionary | Object object NSArray | Array object NSDate | Date object NSBlock (1) | Function object (1) id (2) | Wrapper object (2) Class (3) | Constructor object (3) @/textblock // 在context創建BOOL的JS變量 + (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context; // 將JS變量轉換成OC中的BOOL類型 - (BOOL)toBool; // 修改JS對象的屬性的值 - (void)setValue:(id)value forProperty:(NSString *)property; // JS中是否有這個對象 @property (readonly) BOOL isUndefined; // 比較兩個JS對象是否相等 - (BOOL)isEqualToObject:(id)value; // 調用者JSValue對象為JS中的方法名稱,arguments為參數,調用JS中Window直接調用的方法 - (JSValue *)callWithArguments:(NSArray *)arguments; // 調用者JSValue對象為JS中的全局對象名稱,method為全局對象的方法名稱,arguments為參數 - (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments; // JS中的結構體類型轉換為OC + (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context;JSExport --- JS調用OC中的方法和屬性寫在繼承自JSExport的協議當中,OC對象實現自定義的協議 // textFunction -- JS方法 // - (void) ocTestFunction:(NSNumber *)value sec:(NSNumber *)number -- OC方法 JSExportAs (textFunction,- (void) ocTestFunction:(NSNumber *)value sec:(NSNumber *)number);

JSManagedValue --- JS和OC對象的內存管理輔助對象,主要用來保存JSValue對象,解決OC對象中存儲js的值,導致的循環引用問題

JSManagedValue *_jsManagedValue = [JSManagedValue managedValueWithValue:jsValue];[_context.virtualMachine addManagedReference:_jsManagedValue];

JSManagedValue本身只弱引用js值,需要調用JSVirtualMachine的addManagedReference:withOwner:把它添加到JSVirtualMachine中,這樣如果JavaScript能夠找到該JSValue的Objective-C owner,該JSValue的引用就不會被釋放。

JSVirtualMachine --- JS運行的虛擬機,有獨立的堆空間和垃圾回收機制,運行在不同虛擬機環境的JSContext可以通過此類通信。

Native Code 和 JS 之間的互相調用(以UIWebView中的JS為例)

JS中,點擊事件直接調用方法方式JS和Native代碼的互調如下:

1.1 JS代碼如下

<html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport"><body> <script type="text/javascript"> var nativeCallJS = function(parameter) { alert (parameter); }; </script> <button type="button" onclick = "jsCallNative('jsparameter')" style="width:100%; height:30px;"/>調用OC代碼</button></body></html>

1.2 OC代碼如下

- (void)__jsLogic { self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception){ NSLog(@"JS代碼執行中的異常信息%@", exception); }; self.jsContext = [self valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; self.jsContext[@"jsCallNative"] = ^(NSString *paramer){ JSValue *currentThis = [JSContext currentThis]; JSValue *currentCallee = [JSContext currentCallee]; NSArray *currentParamers = [JSContext currentArguments]; dispatch_async(dispatch_get_main_queue(), ^{ /** * js調起OC代碼,代碼在子線程,更新OC中的UI,需要回到主線程 */ }); NSLog(@"JS paramer is %@",paramer); NSLog(@"currentThis is %@",[currentThis toString]); NSLog(@"currentCallee is %@",[currentCallee toString]); NSLog(@"currentParamers is %@",currentParamers); }; JSValue *jsMethod = self.jsContext[@"nativeCallJS"]; [jsMethod callWithArguments:@[@"nativeCallJS"]]; }1.3 OC運行結果,彈出HTML中的alert提示 2016-08-05 17:57:08.974 LeWebViewPro[38150:3082770] JS paramer is jsParameter 2016-08-05 17:57:08.975 LeWebViewPro[38150:3082770] currentThis is [object Window] 2016-08-05 17:57:08.975 LeWebViewPro[38150:3082770] currentCallee is function () { [native code]} 2016-08-05 17:57:08.975 LeWebViewPro[38150:3082770] currentParamers is ( jsParameter )

JS中,點擊事件等事件通過調用全局對象的方法調用方法,JS和Native代碼的互調如下:

2.1 JS代碼如下

<html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport"> <body> <script type="text/javascript"> globalObject = new Object(); globalObject.name = 100; globalObject.nativeCallJS = function (parameter) { alert (parameter); }; </script> <button type="button" onclick = "globalObject.jsCallNative('jsParameter')" style="width:100%; height:30px;"/>調用OC代碼</button> </body> </html>2.2 OC代碼如下

2.2.1 JSManager 代碼,負責執行JS中的方法

#import <JavaScriptCore/JavaScriptCore.h>#import <Foundation/Foundation.h>@protocol LeJSExport <JSExport>JSExportAs (jsCallNative,- (void) jsCallNative:(NSString *)jsParameter);@end@interface JSManager : NSObject<LeJSExport>@end-----.M文件-----#import "JSManager.h"@implementation JSManager- (void)jsCallNative:(NSString *)jsParameter{ JSValue *currentThis = [JSContext currentThis]; JSValue *currentCallee = [JSContext currentCallee]; NSArray *currentParamers = [JSContext currentArguments]; dispatch_async(dispatch_get_main_queue(), ^{ /** * js調起OC代碼,代碼在子線程,更新OC中的UI,需要回到主線程 */ }); NSLog(@"JS paramer is %@",jsParameter); NSLog(@"currentThis is %@",[currentThis toString]); NSLog(@"currentCallee is %@",[currentCallee toString]); NSLog(@"currentParamers is %@",currentParamers);}@end

2.2.2 包含UIWebView類的代碼,負責調起JS中的方法

- (void)nativeCallJS{ self.jsManager = [[JSManager alloc] init]; self.jsContext = [self valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception){ NSLog(@"JS代碼執行中的異常信息%@", exception); }; self.jsContext[@"globalObject"] = self.jsManager; //1.OC方法調起JS JSValue *varibleStyle = self.jsContext[@"globalObject"]; [varibleStyle invokeMethod:@"nativeCallJS" withArguments:@[@100]]; //2.OC腳本調起JS NSString *jsScript = [NSString stringWithFormat:@"globalObject.nativeCallJS('%@')",@100]; [self.jsContext evaluateScript:jsScript];}

2.3 OC運行結果,彈出HTML中的alert提示

2016-08-07 10:30:11.444 LeWebViewPro[46674:3253852] JS paramer is jsParameter 2016-08-07 10:30:11.444 LeWebViewPro[46674:3253852] currentThis is [object JSManager] 2016-08-07 10:30:11.444 LeWebViewPro[46674:3253852] currentCallee is function () { [native code] } 2016-08-07 10:30:11.445 LeWebViewPro[46674:3253852] currentParamers is ( jsParameter )

JavaScriptCore和UIWebView的使用的注意事項

OC在與UIWebView中的JS交互的邏輯是,先獲取UIWebView中的JS的執行環境 self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];獲取UIWebView中的JS的執行環境的時機,一般在webViewDidFinishLoad時獲取,獲取不到的情況下,需改在其他方法中獲取shouldStartLoadWithRequest:Sent before a web view begins loading a framewebViewDidStartLoad:Sent after a web view starts loading a frame.webViewDidFinishLoad:Sent after a web view finishes loading a frame

線程問題

JavaScriptCore中提供的API都是線程安全的,一個JSVirtualMachine在一個線程中,它可以包含多個JSContext,而且相互之間可以傳值,為了確保線程安全,這些context在運行的時候會采用鎖,可以認為是串行執行。JS調用OC的回調方法,是在子線程,所以需要更新OC中的UI的話,需要切換到主線程

內存問題

oc中使用ARC方式管理內存(基于引用計數),但JavaScriptCore中使用的是垃圾回收方式,其中所有的引用都是強引用,但是我們不必擔心其循環引用,js的垃圾回收能夠打破這些強引用,有些情況需要考慮如下

js調起OC回調的block中獲取JSConetxt容易循環引用

self.jsContext[@"jsCallNative"] = ^(NSString *paramer){ // 會引起循環引用 JSValue *value1 = [JSValue valueWithNewObjectInContext: self.jsContext]; // 不會引起循環引用 JSValue *value = [JSValue valueWithNewObjectInContext: [JSContext currentContext]];};

JavaScriptCore中所有的引用都是強引用,所以在OC中需要存儲JS中的值的時候,需要注意

在oc中為了打破循環引用我們采用weak的方式,不過在JavaScriptCore中我們采用內存管理輔助對象JSManagedValue的方式,它能幫助引用技術和垃圾回收這兩種內存管理機制之間進行正確的轉換

JavaScriptCore單獨使用

js代碼如下test.jsglobalObject = new Object();globalObject.name = 100;globalObject.nativeCallJS = function (parameter) { alert (parameter);};

OC讀取JS文件,并相互通信

NSString *jsPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"js"]; NSString *jsContent = [[NSString alloc] initWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:nil]; JSContext *jsContext = [[JSContext alloc] init]; //捕獲運行js腳本的錯誤信息 jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; NSLog(@"異常信息:%@", exceptionValue); }; //js腳本添加到當前的js執行環境中 [jsContext evaluateScript:jsContent]; self.jsManager = [[JSManager alloc] init]; jsContext[@"globalObject"] = self.jsManager; ... ...

jS與OC的交互與通過UIWebView相同

相關博客

JavaScript和Objective-C交互的那些事

說說JavaScriptCore


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
草民午夜欧美限制a级福利片| 国产精品久久久久久中文字| 伊人成人开心激情综合网| 日韩av免费在线播放| 91综合免费在线| 韩剧1988免费观看全集| 欧美电影免费观看高清完整| 69影院欧美专区视频| 国产成人精品电影久久久| 亚洲有声小说3d| 中文字幕亚洲色图| 亚洲欧洲激情在线| 日韩av中文字幕在线播放| 欧美成人免费在线观看| 精品日本美女福利在线观看| 国产精品女人久久久久久| 粉嫩老牛aⅴ一区二区三区| 成人在线播放av| 亚洲精品国产精品国自产观看浪潮| 久久久99免费视频| 国产精品9999| 国模私拍一区二区三区| 92版电视剧仙鹤神针在线观看| 欧美激情国内偷拍| 日韩美女av在线免费观看| 国产精品一久久香蕉国产线看观看| 日韩中文字幕免费| 亚洲综合小说区| 欧美激情高清视频| 久久91亚洲精品中文字幕| 亚洲精品综合久久中文字幕| 日韩色av导航| 欧美日韩一区二区免费视频| 亚洲欧美精品中文字幕在线| 尤物yw午夜国产精品视频明星| 亚洲91精品在线观看| 亚洲精品视频久久| 91香蕉嫩草神马影院在线观看| 7777精品久久久久久| 久久久999成人| 91精品在线观| 毛片精品免费在线观看| 欧美视频一区二区三区…| 人人爽久久涩噜噜噜网站| 九色精品美女在线| 日韩专区在线播放| 亚洲人线精品午夜| 亲爱的老师9免费观看全集电视剧| 精品呦交小u女在线| 亚洲网在线观看| 精品国偷自产在线| 日韩在线观看免费| 欧美日韩一区二区免费视频| 国模精品视频一区二区三区| 欧美俄罗斯性视频| 日韩欧美一区二区在线| 91精品国产777在线观看| 国产精品视频在线播放| 成人观看高清在线观看免费| 国产精品99导航| 精品视频—区二区三区免费| 欧美激情免费观看| 热re91久久精品国99热蜜臀| 亚洲性xxxx| 国产精品成人播放| 亚洲资源在线看| 国产丝袜一区二区三区| 亚洲高清久久网| 欧美一区二区三区免费观看| 成人女保姆的销魂服务| 国模视频一区二区三区| 久久精品国产96久久久香蕉| 97视频网站入口| 96pao国产成视频永久免费| 欧美一级淫片videoshd| 成人免费视频a| 日韩美女视频中文字幕| 国产精品欧美日韩一区二区| xxxxxxxxx欧美| 亚洲综合最新在线| 久久91精品国产91久久久| 国产精品日日摸夜夜添夜夜av| 欧美日韩中文在线| 91经典在线视频| 亚洲伊人久久综合| 久久人人爽人人爽人人片av高请| 在线观看久久久久久| 影音先锋欧美在线资源| 久久久久久久久久久亚洲| 91香蕉国产在线观看| 国产精品一区二区久久国产| 精品亚洲国产成av人片传媒| 欧美性生活大片免费观看网址| 国产精品99一区| 国产精品美女在线| 成人自拍性视频| 国产a∨精品一区二区三区不卡| 亚洲欧美999| 亚洲国产精彩中文乱码av在线播放| 亚洲高清免费观看高清完整版| 欧美电影《睫毛膏》| 欧美黄色片视频| 国产欧美va欧美va香蕉在线| 17婷婷久久www| 欧美日韩亚洲一区二区三区| 欧美亚洲国产成人精品| 日本欧美国产在线| 国产成人拍精品视频午夜网站| 中国日韩欧美久久久久久久久| 日韩va亚洲va欧洲va国产| 成人疯狂猛交xxx| 久久精品在线视频| 亚洲伊人第一页| 精品亚洲夜色av98在线观看| 国产精品99蜜臀久久不卡二区| 久久97久久97精品免视看| 91最新在线免费观看| 亚洲精品国产成人| 欧美激情中文字幕在线| 国产精品久久9| 国产丝袜高跟一区| 亚洲sss综合天堂久久| 中文字幕欧美日韩精品| 亚洲**2019国产| 久久6免费高清热精品| 欧美黑人又粗大| 国内精品视频久久| 国产精品2018| www.久久久久| 在线午夜精品自拍| 色综合视频一区中文字幕| 国语自产在线不卡| 国产美女精品视频| 亚洲成人a级网| 久久亚洲精品国产亚洲老地址| 亚洲精品国产精品久久清纯直播| 日韩在线观看免费高清| 国产成人精品国内自产拍免费看| 国产a级全部精品| 国产精品毛片a∨一区二区三区|国| 久久精品99久久久久久久久| 97色在线播放视频| 国产一区二区三区在线免费观看| 久久久免费在线观看| 狠狠色狠色综合曰曰| 91九色国产社区在线观看| 久久久精品影院| 最近日韩中文字幕中文| 色噜噜狠狠色综合网图区| 欧美黑人又粗大| 98精品国产自产在线观看| 欧美影院久久久| 精品久久久久久久久国产字幕| 久色乳综合思思在线视频| 日本成人黄色片| 中文字幕久久精品| 国模极品一区二区三区| 亚洲国产欧美一区二区三区同亚洲| 少妇精69xxtheporn| 午夜精品一区二区三区在线播放| 欧美xxxwww| 国产精品狼人色视频一区| 啊v视频在线一区二区三区| 日韩av黄色在线观看|