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

首頁 > 編程 > JavaScript > 正文

JavaScriptCore詳解

2019-11-06 09:59:02
字體:
來源:轉載
供稿:網友

本博客主要分以下幾個方面來介紹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
国产91精品网站| 成人综合国产精品| 久久久久久九九九| 懂色av中文一区二区三区天美| 精品在线观看国产| 国产精品麻豆va在线播放| 国产精品视频网站| 91精品国产综合久久香蕉最新版| 日韩精品中文字幕在线播放| 日韩一级裸体免费视频| 国产精品久久国产精品99gif| 黑人精品xxx一区| 亚洲免费人成在线视频观看| 全亚洲最色的网站在线观看| 在线观看国产精品日韩av| 成人黄色短视频在线观看| 亚洲国产天堂久久综合网| 91亚洲国产成人精品性色| 久久久999国产| 成人性生交大片免费看视频直播| 亚洲第一精品夜夜躁人人躁| 欧美人在线观看| 日韩欧美在线免费观看| 亚洲免费视频在线观看| 成人国产精品久久久久久亚洲| 亚洲裸体xxxx| 欧美久久精品午夜青青大伊人| 亚洲综合色激情五月| 成人免费淫片aa视频免费| 国产精品一区av| 国产欧美精品一区二区三区-老狼| 久久综合电影一区| 久久色免费在线视频| 国产欧美亚洲精品| 神马久久桃色视频| 91久久在线观看| 亚洲欧洲美洲在线综合| 亚洲激情 国产| 日韩在线观看免费av| 国产日产欧美精品| 国产精品扒开腿做爽爽爽视频| 欧美理论片在线观看| 日韩欧美在线字幕| 红桃av永久久久| 国产精品中文字幕久久久| 久久久噜噜噜久噜久久| 成人有码在线视频| 亚洲电影免费观看高清完整版在线| 亚洲aa中文字幕| 91日本视频在线| 欧美精品电影免费在线观看| 久久国产精彩视频| 亚洲缚视频在线观看| 国产一区香蕉久久| 亚洲高清久久网| 91chinesevideo永久地址| 国产精品电影网站| 久久99亚洲精品| 欧美精品免费播放| 91精品视频专区| 在线精品高清中文字幕| 欧美xxxx14xxxxx性爽| 92看片淫黄大片看国产片| 久久精品一偷一偷国产| 精品久久久久久久久国产字幕| 亚洲一区制服诱惑| 国产成人一区二区三区小说| 亚洲精品电影久久久| 97精品久久久| 亚洲精品丝袜日韩| 国产一区深夜福利| xxxx欧美18另类的高清| 中文字幕国产精品| 久久精品91久久香蕉加勒比| …久久精品99久久香蕉国产| 69久久夜色精品国产7777| 久久韩剧网电视剧| 亚洲精品美女在线| 亚洲精品aⅴ中文字幕乱码| 欧美一级淫片videoshd| 97久久国产精品| 97视频在线观看视频免费视频| 久久av在线看| 亚洲精品网址在线观看| 亚洲天堂2020| 国产精品视频1区| 久久99热精品| 欧美性色19p| 国产福利精品视频| 精品亚洲一区二区三区| 日韩av在线最新| 影音先锋欧美精品| 国产一级揄自揄精品视频| 亚洲日本成人女熟在线观看| 日韩不卡在线观看| 日韩**中文字幕毛片| 欧美性视频网站| 国产女精品视频网站免费| 国产精品一区二区三区成人| 97国产在线观看| 国产性猛交xxxx免费看久久| 欧美日韩激情小视频| 国产成人+综合亚洲+天堂| 国产视频综合在线| 日本一区二区三区四区视频| 欧美激情xxxx| 亚洲日本aⅴ片在线观看香蕉| 成人激情电影一区二区| 欧美亚洲另类在线| 亚洲区中文字幕| 日本欧美一级片| 亚洲精品电影久久久| 国产99视频在线观看| 亚洲欧洲国产精品| 欧美国产中文字幕| 中文字幕日本精品| 色婷婷久久一区二区| 久久99精品视频一区97| 国产精品久久久久久搜索| 欧美老肥婆性猛交视频| 欧美xxxwww| 亚洲欧美制服中文字幕| 午夜精品一区二区三区在线视| 欧美激情伊人电影| 美女精品久久久| 亚洲一区美女视频在线观看免费| 亚洲小视频在线| 成人性生交大片免费看视频直播| 8x海外华人永久免费日韩内陆视频| 久久精品国产2020观看福利| 国产一区二区三区精品久久久| 国产精品爽爽ⅴa在线观看| 久久久女女女女999久久| 狠狠久久五月精品中文字幕| 国产丝袜一区视频在线观看| 欧美理论电影在线观看| 日韩欧美在线播放| 成人激情av在线| 欧美日韩成人黄色| 欧美在线一级va免费观看| 国产91精品久久久久久久| 日韩在线视频中文字幕| 国产一区二区三区在线免费观看| 亚洲国产小视频在线观看| 91视频国产高清| 动漫精品一区二区| 亚洲久久久久久久久久| 亚洲免费一在线| 亚洲丁香久久久| 成人乱人伦精品视频在线观看| 另类少妇人与禽zozz0性伦| 国产成人精品电影| 中文字幕日韩欧美精品在线观看| 欧美日韩国产中字| 亚洲精品久久7777777| 另类少妇人与禽zozz0性伦| 亚洲国产天堂久久国产91| 日韩亚洲精品电影| 国产美女精品视频免费观看| 亚洲欧美中文另类| 欧美日本高清一区| 国产精品免费久久久久久| 国产精品免费一区二区三区都可以| 亚洲自拍偷拍在线|