国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScriptCore全面解析

OnlyMyRailgun / 2061人閱讀

摘要:可嵌入動(dòng)態(tài)文本于頁面,對(duì)瀏覽器事件作出響應(yīng),讀寫元素,控制等。年月,發(fā)布了一款面向普通用戶的新一代的瀏覽器版,市場(chǎng)份額一舉超過。網(wǎng)景將這門語言作為標(biāo)準(zhǔn)提交給了歐洲計(jì)算機(jī)制造協(xié)會(huì)。線程和的并發(fā)執(zhí)行都是線程安全的。后面會(huì)詳細(xì)講解對(duì)象類型的轉(zhuǎn)換。

本文由云+社區(qū)發(fā)表

作者:殷源,專注移動(dòng)客戶端開發(fā),微軟Imagine Cup中國(guó)區(qū)特等獎(jiǎng)獲得者

JavaScript越來越多地出現(xiàn)在我們客戶端開發(fā)的視野中,從ReactNative到JSpatch,JavaScript與客戶端相結(jié)合的技術(shù)開始變得魅力無窮。本文主要講解iOS中的JavaScriptCore框架,正是它為iOS提供了執(zhí)行JavaScript代碼的能力。未來的技術(shù)日新月異,JavaScript與iOS正在碰撞出新的激情。

JavaScriptCore是JavaScript的虛擬機(jī),為JavaScript的執(zhí)行提供底層資源。

一、JavaScript

在討論JavaScriptCore之前,我們首先必須對(duì)JavaScript有所了解。

1. JavaScript干啥的?

說的高大上一點(diǎn):一門基于原型、函數(shù)先行的高級(jí)編程語言,通過解釋執(zhí)行,是動(dòng)態(tài)類型的直譯語言。是一門多范式的語言,它支持面向?qū)ο缶幊蹋钍骄幊蹋约昂瘮?shù)式編程。

說的通俗一點(diǎn):主要用于網(wǎng)頁,為其提供動(dòng)態(tài)交互的能力。可嵌入動(dòng)態(tài)文本于HTML頁面,對(duì)瀏覽器事件作出響應(yīng),讀寫HTML元素,控制cookies等。

再通俗一點(diǎn):搶月餅,button.click()。(PS:請(qǐng)謹(jǐn)慎使用while循環(huán))

2. JavaScript起源與歷史

1990年底,歐洲核能研究組織(CERN)科學(xué)家Tim Berners-Lee,在互聯(lián)網(wǎng)的基礎(chǔ)上,發(fā)明了萬維網(wǎng)(World Wide Web),從此可以在網(wǎng)上瀏覽網(wǎng)頁文件。

1994年12月,Netscape 發(fā)布了一款面向普通用戶的新一代的瀏覽器Navigator 1.0版,市場(chǎng)份額一舉超過90%。

1995年,Netscape公司雇傭了程序員Brendan Eich開發(fā)這種嵌入網(wǎng)頁的腳本語言。最初名字叫做Mocha,1995年9月改為L(zhǎng)iveScript。

1995年12月,Netscape公司與Sun公司達(dá)成協(xié)議,后者允許將這種語言叫做JavaScript。

3. JavaScript與ECMAScript

“JavaScript”是Sun公司的注冊(cè)商標(biāo),用來特制網(wǎng)景(現(xiàn)在的Mozilla)對(duì)于這門語言的實(shí)現(xiàn)。網(wǎng)景將這門語言作為標(biāo)準(zhǔn)提交給了ECMA——?dú)W洲計(jì)算機(jī)制造協(xié)會(huì)。由于商標(biāo)上的沖突,這門語言的標(biāo)準(zhǔn)版本改了一個(gè)丑陋的名字“ECMAScript”。同樣由于商標(biāo)的沖突,微軟對(duì)這門語言的實(shí)現(xiàn)版本取了一個(gè)廣為人知的名字“Jscript”。

ECMAScript作為JavaScript的標(biāo)準(zhǔn),一般認(rèn)為后者是前者的實(shí)現(xiàn)。

4. Java和JavaScript

《雷鋒和雷峰塔》

Java 和 JavaScript 是兩門不同的編程語言 一般認(rèn)為,當(dāng)時(shí) Netscape 之所以將 LiveScript 命名為 JavaScript,是因?yàn)?Java 是當(dāng)時(shí)最流行的編程語言,帶有 “Java” 的名字有助于這門新生語言的傳播。

二、 JavaScriptCore 1. 瀏覽器演進(jìn)

演進(jìn)完整圖

https://upload.wikimedia.org/...

WebKit分支

現(xiàn)在使用WebKit的主要兩個(gè)瀏覽器Sfari和Chromium(Chorme的開源項(xiàng)目)。WebKit起源于KDE的開源項(xiàng)目Konqueror的分支,由蘋果公司用于Sfari瀏覽器。其一條分支發(fā)展成為Chorme的內(nèi)核,2013年Google在此基礎(chǔ)上開發(fā)了新的Blink內(nèi)核。

2. WebKit排版引擎

webkit是sfari、chrome等瀏覽器的排版引擎,各部分架構(gòu)圖如下

webkit Embedding API是browser UI與webpage進(jìn)行交互的api接口;

platformAPI提供與底層驅(qū)動(dòng)的交互, 如網(wǎng)絡(luò), 字體渲染, 影音文件解碼, 渲染引擎等;

WebCore它實(shí)現(xiàn)了對(duì)文檔的模型化,包括了CSS, DOM, Render等的實(shí)現(xiàn);

JSCore是專門處理JavaScript腳本的引擎;

3. JavaScript引擎

JavaScript引擎是專門處理JavaScript腳本的虛擬機(jī),一般會(huì)附帶在網(wǎng)頁瀏覽器之中。第一個(gè)JavaScript引擎由布蘭登·艾克在網(wǎng)景公司開發(fā),用于Netscape Navigator網(wǎng)頁瀏覽器中。JavaScriptCore就是一個(gè)JavaScript引擎。

下圖是當(dāng)前主要的還在開發(fā)中的JavaScript引擎

4. JavaScriptCore組成

JavaScriptCore主要由以下模塊組成:

Lexer 詞法分析器,將腳本源碼分解成一系列的Token

Parser 語法分析器,處理Token并生成相應(yīng)的語法樹

LLInt 低級(jí)解釋器,執(zhí)行Parser生成的二進(jìn)制代碼

Baseline JIT 基線JIT(just in time 實(shí)施編譯)

DFG 低延遲優(yōu)化的JIT

FTL 高通量?jī)?yōu)化的JIT

關(guān)于更多JavaScriptCore的實(shí)現(xiàn)細(xì)節(jié),參考 https://trac.webkit.org/wiki/...

5. JavaScriptCore

JavaScriptCore是一個(gè)C++實(shí)現(xiàn)的開源項(xiàng)目。使用Apple提供的JavaScriptCore框架,你可以在Objective-C或者基于C的程序中執(zhí)行Javascript代碼,也可以向JavaScript環(huán)境中插入一些自定義的對(duì)象。JavaScriptCore從iOS 7.0之后可以直接使用。

在JavaScriptCore.h中,我們可以看到這個(gè)

#ifndef JavaScriptCore_h
#define JavaScriptCore_h

#include 
#include 

#if defined(__OBJC__) && JSC_OBJC_API_ENABLED

#import "JSContext.h"
#import "JSValue.h"
#import "JSManagedValue.h"
#import "JSVirtualMachine.h"
#import "JSExport.h"

#endif

#endif /* JavaScriptCore_h */

這里已經(jīng)很清晰地列出了JavaScriptCore的主要幾個(gè)類:

JSContext

JSValue

JSManagedValue

JSVirtualMachine

JSExport

接下來我們會(huì)依次講解這幾個(gè)類的用法。

6. Hello World!

這段代碼展示了如何在Objective-C中執(zhí)行一段JavaScript代碼,并且獲取返回值并轉(zhuǎn)換成OC數(shù)據(jù)打印

//創(chuàng)建虛擬機(jī)
JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];

//創(chuàng)建上下文
JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];

//執(zhí)行JavaScript代碼并獲取返回值
JSValue *value = [context evaluateScript:@"1+2*3"];

//轉(zhuǎn)換成OC數(shù)據(jù)并打印
NSLog(@"value = %d", [value toInt32]);

Output

value = 7
三、 JSVirtualMachine

一個(gè)JSVirtualMachine的實(shí)例就是一個(gè)完整獨(dú)立的JavaScript的執(zhí)行環(huán)境,為JavaScript的執(zhí)行提供底層資源。

這個(gè)類主要用來做兩件事情:

實(shí)現(xiàn)并發(fā)的JavaScript執(zhí)行

JavaScript和Objective-C橋接對(duì)象的內(nèi)存管理

看下頭文件SVirtualMachine.h里有什么:

NS_CLASS_AVAILABLE(10_9, 7_0)
@interface JSVirtualMachine : NSObject

/* 創(chuàng)建一個(gè)新的完全獨(dú)立的虛擬機(jī) */
(instancetype)init;

/* 對(duì)橋接對(duì)象進(jìn)行內(nèi)存管理 */
- (void)addManagedReference:(id)object withOwner:(id)owner;

/* 取消對(duì)橋接對(duì)象的內(nèi)存管理 */
- (void)removeManagedReference:(id)object withOwner:(id)owner;

@end

每一個(gè)JavaScript上下文(JSContext對(duì)象)都?xì)w屬于一個(gè)虛擬機(jī)(JSVirtualMachine)。每個(gè)虛擬機(jī)可以包含多個(gè)不同的上下文,并允許在這些不同的上下文之間傳值(JSValue對(duì)象)。

然而,每個(gè)虛擬機(jī)都是完整且獨(dú)立的,有其獨(dú)立的堆空間和垃圾回收器(garbage collector ),GC無法處理別的虛擬機(jī)堆中的對(duì)象,因此你不能把一個(gè)虛擬機(jī)中創(chuàng)建的值傳給另一個(gè)虛擬機(jī)。

線程和JavaScript的并發(fā)執(zhí)行

JavaScriptCore API都是線程安全的。你可以在任意線程創(chuàng)建JSValue或者執(zhí)行JS代碼,然而,所有其他想要使用該虛擬機(jī)的線程都要等待。

如果想并發(fā)執(zhí)行JS,需要使用多個(gè)不同的虛擬機(jī)來實(shí)現(xiàn)。

可以在子線程中執(zhí)行JS代碼。

通過下面這個(gè)demo來理解一下這個(gè)并發(fā)機(jī)制

JSContext *context = [[CustomJSContext alloc] init];
JSContext *context1 = [[CustomJSContext alloc] init];
JSContext *context2 = [[CustomJSContext alloc] initWithVirtualMachine:[context virtualMachine]];
NSLog(@"start");
dispatch_async(queue, ^{
    while (true) {
        sleep(1);
        [context evaluateScript:@"log("tick")"];
    }
});
dispatch_async(queue1, ^{
    while (true) {
        sleep(1);
        [context1 evaluateScript:@"log("tick_1")"];
    }
});
dispatch_async(queue2, ^{
    while (true) {
        sleep(1);
        [context2 evaluateScript:@"log("tick_2")"];
    }
});
[context evaluateScript:@"sleep(5)"];
NSLog(@"end");

context和context2屬于同一個(gè)虛擬機(jī)。

context1屬于另一個(gè)虛擬機(jī)。

三個(gè)線程分別異步執(zhí)行每秒1次的js log,首先會(huì)休眠1秒。

在context上執(zhí)行一個(gè)休眠5秒的JS函數(shù)。

首先執(zhí)行的應(yīng)該是休眠5秒的JS函數(shù),在此期間,context所處的虛擬機(jī)上的其他調(diào)用都會(huì)處于等待狀態(tài),因此tick和tick_2在前5秒都不會(huì)有執(zhí)行。

而context1所處的虛擬機(jī)仍然可以正常執(zhí)行tick_1

休眠5秒結(jié)束后,tick和tick_2才會(huì)開始執(zhí)行(不保證先后順序)。

實(shí)際運(yùn)行輸出的log是:

start
tick_1
tick_1
tick_1
tick_1
end
tick
tick_2
四、 JSContext

一個(gè)JSContext對(duì)象代表一個(gè)JavaScript執(zhí)行環(huán)境。在native代碼中,使用JSContext去執(zhí)行JS代碼,訪問JS中定義或者計(jì)算的值,并使JavaScript可以訪問native的對(duì)象、方法、函數(shù)。

1. JSContext執(zhí)行JS代碼

調(diào)用evaluateScript函數(shù)可以執(zhí)行一段top-level 的JS代碼,并可向global對(duì)象添加函數(shù)和對(duì)象定義

其返回值是JavaScript代碼中最后一個(gè)生成的值

API Reference

NS_CLASS_AVAILABLE(10_9, 7_0)
@interface JSContext : NSObject

/* 創(chuàng)建一個(gè)JSContext,同時(shí)會(huì)創(chuàng)建一個(gè)新的JSVirtualMachine */
(instancetype)init;

/* 在指定虛擬機(jī)上創(chuàng)建一個(gè)JSContext */
(instancetype)initWithVirtualMachine:
        (JSVirtualMachine*)virtualMachine;

/* 執(zhí)行一段JS代碼,返回最后生成的一個(gè)值 */
(JSValue *)evaluateScript:(NSString *)script;

/* 執(zhí)行一段JS代碼,并將sourceURL認(rèn)作其源碼URL(僅作標(biāo)記用) */
- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL*)sourceURL     NS_AVAILABLE(10_10, 8_0);

/* 獲取當(dāng)前執(zhí)行的JavaScript代碼的context */
+ (JSContext *)currentContext;

/* 獲取當(dāng)前執(zhí)行的JavaScript function*/
+ (JSValue *)currentCallee NS_AVAILABLE(10_10, 8_0);

/* 獲取當(dāng)前執(zhí)行的JavaScript代碼的this */
+ (JSValue *)currentThis;

/* Returns the arguments to the current native callback from JavaScript code.*/
+ (NSArray *)currentArguments;

/* 獲取當(dāng)前context的全局對(duì)象。WebKit中的context返回的便是WindowProxy對(duì)象*/
@property (readonly, strong) JSValue *globalObject;

@property (strong) JSValue *exception;
@property (copy) void(^exceptionHandler)(JSContext *context, JSValue
    *exception);

@property (readonly, strong) JSVirtualMachine *virtualMachine;

@property (copy) NSString *name NS_AVAILABLE(10_10, 8_0);


@end
2. JSContext訪問JS對(duì)象

一個(gè)JSContext對(duì)象對(duì)應(yīng)了一個(gè)全局對(duì)象(global object)。例如web瀏覽器中中的JSContext,其全局對(duì)象就是window對(duì)象。在其他環(huán)境中,全局對(duì)象也承擔(dān)了類似的角色,用來區(qū)分不同的JavaScript context的作用域。全局變量是全局對(duì)象的屬性,可以通過JSValue對(duì)象或者context下標(biāo)的方式來訪問。

一言不合上代碼:

JSValue *value = [context evaluateScript:@"var a = 1+2*3;"];

NSLog(@"a = %@", [context objectForKeyedSubscript:@"a"]);
NSLog(@"a = %@", [context.globalObject objectForKeyedSubscript:@"a"]);
NSLog(@"a = %@", context[@"a"]);

/
Output:

a = 7
a = 7
a = 7

這里列出了三種訪問JavaScript對(duì)象的方法

通過context的實(shí)例方法objectForKeyedSubscript

通過context.globalObject的objectForKeyedSubscript實(shí)例方法

通過下標(biāo)方式

設(shè)置屬性也是對(duì)應(yīng)的。

API Reference

/* 為JSContext提供下標(biāo)訪問元素的方式 */
@interface JSContext (SubscriptSupport)

/* 首先將key轉(zhuǎn)為JSValue對(duì)象,然后使用這個(gè)值在JavaScript context的全局對(duì)象中查找這個(gè)名字的屬性并返回 */
(JSValue *)objectForKeyedSubscript:(id)key;

/* 首先將key轉(zhuǎn)為JSValue對(duì)象,然后用這個(gè)值在JavaScript context的全局對(duì)象中設(shè)置這個(gè)屬性。
可使用這個(gè)方法將native中的對(duì)象或者方法橋接給JavaScript調(diào)用 */
(void)setObject:(id)object forKeyedSubscript:(NSObject *)key;

@end



/* 例如:以下代碼在JavaScript中創(chuàng)建了一個(gè)實(shí)現(xiàn)是Objective-C block的function */
context[@"makeNSColor"] = ^(NSDictionary *rgb){
    float r = [rgb[@"red"] floatValue];
    float g = [rgb[@"green"] floatValue];
    float b = [rgb[@"blue"] floatValue];
    return [NSColor colorWithRed:(r / 255.f) green:(g / 255.f) blue:(b / 255.f)         alpha:1.0];
};
JSValue *value = [context evaluateScript:@"makeNSColor({red:12, green:23, blue:67})"];
五、 JSValue

一個(gè)JSValue實(shí)例就是一個(gè)JavaScript值的引用。使用JSValue類在JavaScript和native代碼之間轉(zhuǎn)換一些基本類型的數(shù)據(jù)(比如數(shù)值和字符串)。你也可以使用這個(gè)類去創(chuàng)建包裝了自定義類的native對(duì)象的JavaScript對(duì)象,或者創(chuàng)建由native方法或者block實(shí)現(xiàn)的JavaScript函數(shù)。

每個(gè)JSValue實(shí)例都來源于一個(gè)代表JavaScript執(zhí)行環(huán)境的JSContext對(duì)象,這個(gè)執(zhí)行環(huán)境就包含了這個(gè)JSValue對(duì)應(yīng)的值。每個(gè)JSValue對(duì)象都持有其JSContext對(duì)象的強(qiáng)引用,只要有任何一個(gè)與特定JSContext關(guān)聯(lián)的JSValue被持有(retain),這個(gè)JSContext就會(huì)一直存活。通過調(diào)用JSValue的實(shí)例方法返回的其他的JSValue對(duì)象都屬于與最始的JSValue相同的JSContext。

每個(gè)JSValue都通過其JSContext間接關(guān)聯(lián)了一個(gè)特定的代表執(zhí)行資源基礎(chǔ)的JSVirtualMachine對(duì)象。你只能將一個(gè)JSValue對(duì)象傳給由相同虛擬機(jī)管理(host)的JSValue或者JSContext的實(shí)例方法。如果嘗試把一個(gè)虛擬機(jī)的JSValue傳給另一個(gè)虛擬機(jī),將會(huì)觸發(fā)一個(gè)Objective-C異常。

1. JSValue類型轉(zhuǎn)換

JSValue提供了一系列的方法將native與JavaScript的數(shù)據(jù)類型進(jìn)行相互轉(zhuǎn)換:

2. NSDictionary與JS對(duì)象

NSDictionary對(duì)象以及其包含的keys與JavaScript中的對(duì)應(yīng)名稱的屬性相互轉(zhuǎn)換。key所對(duì)應(yīng)的值也會(huì)遞歸地進(jìn)行拷貝和轉(zhuǎn)換。

[context evaluateScript:@"var color = {red:230, green:90, blue:100}"];

//js->native 給你看我的顏色
JSValue *colorValue = context[@"color"];
NSLog(@"r=%@, g=%@, b=%@", colorValue[@"red"], colorValue[@"green"], colorValue[@"blue"]);
NSDictionary *colorDic = [colorValue toDictionary];
NSLog(@"r=%@, g=%@, b=%@", colorDic[@"red"], colorDic[@"green"], colorDic[@"blue"]);

//native->js 給你點(diǎn)顏色看看
context[@"color"] = @{@"red":@(0), @"green":@(0), @"blue":@(0)};
[context evaluateScript:@"log("r:"+color.red+"g:"+color.green+" b:"+color.blue)"];
Output:

r=230, g=90, b=100
r=230, g=90, b=100
r:0 g:0 b:0

可見,JS中的對(duì)象可以直接轉(zhuǎn)換成Objective-C中的NSDictionary,NSDictionary傳入JavaScript也可以直接當(dāng)作對(duì)象被使用。

3. NSArray與JS數(shù)組

NSArray對(duì)象與JavaScript中的array相互轉(zhuǎn)轉(zhuǎn)。其子元素也會(huì)遞歸地進(jìn)行拷貝和轉(zhuǎn)換。

[context evaluateScript:@“var friends = ["Alice","Jenny","XiaoMing"]"];

//js->native 你說哪個(gè)是真愛?
JSValue *friendsValue = context[@"friends"];
NSLog(@"%@, %@, %@", friendsValue[0], friendsValue[1], friendsValue[2]);
NSArray *friendsArray = [friendsValue toArray];
NSLog(@"%@, %@, %@", friendsArray[0], friendsArray[1], friendsArray[2]);

//native->js 我覺XiaoMing和不不錯(cuò),給你再推薦個(gè)Jimmy
context[@"girlFriends"] = @[friendsArray[2], @"Jimmy"];
[context evaluateScript:@"log("girlFriends :"+girlFriends[0]+" "+girlFriends[1])"];

Output:

Alice, Jenny, XiaoMing
Alice, Jenny, XiaoMing
girlFriends : XiaoMing Jimmy
4. Block/函數(shù)和JS function

Objective-C中的block轉(zhuǎn)換成JavaScript中的function對(duì)象。參數(shù)以及返回類型使用相同的規(guī)則轉(zhuǎn)換。

將一個(gè)代表native的block或者方法的JavaScript function進(jìn)行轉(zhuǎn)換將會(huì)得到那個(gè)block或方法。

其他的JavaScript函數(shù)將會(huì)被轉(zhuǎn)換為一個(gè)空的dictionary。因?yàn)镴avaScript函數(shù)也是一個(gè)對(duì)象。

5. OC對(duì)象和JS對(duì)象

對(duì)于所有其他native的對(duì)象類型,JavaScriptCore都會(huì)創(chuàng)建一個(gè)擁有constructor原型鏈的wrapper對(duì)象,用來反映native類型的繼承關(guān)系。默認(rèn)情況下,native對(duì)象的屬性和方法并不會(huì)導(dǎo)出給其對(duì)應(yīng)的JavaScript wrapper對(duì)象。通過JSExport協(xié)議可選擇性地導(dǎo)出屬性和方法。

后面會(huì)詳細(xì)講解對(duì)象類型的轉(zhuǎn)換。

此文已由騰訊云+社區(qū)在各渠道發(fā)布

獲取更多新鮮技術(shù)干貨,可以關(guān)注我們騰訊云技術(shù)社區(qū)-云加社區(qū)官方號(hào)及知乎機(jī)構(gòu)號(hào)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/101319.html

相關(guān)文章

  • React的移動(dòng)端和PC端生態(tài)圈的使用匯總

    摘要:調(diào)用通過注冊(cè)表調(diào)用到實(shí)例,透過的,調(diào)用到中的,最后通過,調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對(duì)于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問題和優(yōu)化...

    kun_jian 評(píng)論0 收藏0
  • React的移動(dòng)端和PC端生態(tài)圈的使用匯總

    摘要:調(diào)用通過注冊(cè)表調(diào)用到實(shí)例,透過的,調(diào)用到中的,最后通過,調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對(duì)于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問題和優(yōu)化...

    J4ck_Chan 評(píng)論0 收藏0
  • React的移動(dòng)端和PC端生態(tài)圈的使用匯總

    摘要:調(diào)用通過注冊(cè)表調(diào)用到實(shí)例,透過的,調(diào)用到中的,最后通過,調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對(duì)于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問題和優(yōu)化...

    Travis 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<