Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
React NativeͨÐÅ»úÖÆÏê½â
 
  2348  次浏览      27
 2018-1-16 
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚblog.cnbang.net,ÎÄÕµĹؼüµãÄ£¿é»¯£¬Ä£¿éÅäÖÃ±í£¬´«µÝID£¬·â×°µ÷Óã¬Ê¼þÏìÓ¦£¬ÆäÉè¼ÆË¼ÏëºÍʵÏÖ·½·¨ºÜÖµµÃѧϰ¡£

React NativeÊÇfacebook¸Õ¿ªÔ´µÄ¿ò¼Ü£¬¿ÉÒÔÓÃjavascriptÖ±½Ó¿ª·¢Ô­ÉúAPP£¬ÏȲ»ËµÕâ¸ö¿ò¼ÜºóÐøÊÇ·ñÄܵõ½´óÖÚÈϿɣ¬µ¥´ÓÔ´ÂëÀ´Ëµ£¬Õâ¸ö¿ò¼ÜÔ´ÂëÀïÓзdz£¶àµÄÉè¼ÆË¼ÏëºÍʵÏÖ·½Ê½ÖµµÃѧϰ£¬±¾ÆªÏÈÀ´¿´¿´Ëü×î»ù´¡µÄJavaScript-ObjectCͨÐÅ»úÖÆ(ÒÔϼò³ÆJS/OC)¡£

¸ÅÀÀ

React NativeÓÃiOS×Ô´øµÄJavaScriptCore×÷ΪJSµÄ½âÎöÒýÇæ£¬µ«²¢Ã»ÓÐÓõ½JavaScriptCoreÌṩµÄһЩ¿ÉÒÔÈÃJSÓëOC»¥µ÷µÄÌØÐÔ£¬¶øÊÇ×Ô¼ºÊµÏÖÁËÒ»Ì×»úÖÆ£¬ÕâÌ×»úÖÆ¿ÉÒÔͨÓÃÓÚËùÓÐJSÒýÇæÉÏ£¬ÔÚûÓÐJavaScriptCoreµÄÇé¿öÏÂÒ²¿ÉÒÔÓÃwebview´úÌæ£¬Êµ¼ÊÉÏÏîÄ¿Àï¾ÍÒѾ­ÓÐÁËÓÃwebview×÷Ϊ½âÎöÒýÇæµÄʵÏÖ£¬Ó¦¸ÃÊÇÓÃÓÚ¼æÈÝiOS7ÒÔÏÂûÓÐJavascriptCoreµÄ°æ±¾¡£

ÆÕͨµÄJS-OCͨÐÅʵ¼ÊÉϺܼòµ¥£¬OCÏòJS´«ÐÅÏ¢ÓÐÏֳɵĽӿڣ¬ÏñwebviewÌṩµÄ-stringByEvaluatingJavaScriptFromString·½·¨¿ÉÒÔÖ±½ÓÔÚµ±Ç°contextÉÏÖ´ÐÐÒ»¶ÎJS½Å±¾£¬²¢ÇÒ¿ÉÒÔ»ñȡִÐкóµÄ·µ»ØÖµ£¬Õâ¸ö·µ»ØÖµ¾ÍÏ൱ÓÚJSÏòOC´«µÝÐÅÏ¢¡£React NativeÒ²ÊÇÒÔ´ËΪ»ù´¡£¬Í¨¹ý¸÷ÖÖÊֶΣ¬ÊµÏÖÁËÔÚOC¶¨ÒåÒ»¸öÄ£¿é·½·¨£¬JS¿ÉÒÔÖ±½Óµ÷ÓÃÕâ¸öÄ£¿é·½·¨²¢»¹¿ÉÒÔÎÞ·ìÏνӻص÷¡£

¾Ù¸öÀý×Ó£¬OC¶¨ÒåÁËÒ»¸öÄ£¿éRCTSQLManager£¬ÀïÃæÓиö·½·¨-query:successCallback:£¬JS¿ÉÒÔÖ±½Óµ÷ÓÃRCTSQLManager.query²¢Í¨¹ý»Øµ÷»ñȡִÐнá¹û¡££º

//OC:
@implement RCTSQLManager
- (void)query:(NSString *)queryData successCallback:(RCTResponseSenderBlOCk)responseSender
{
RCT_EXPORT();
NSString *ret = @"ret"
responseSender(ret);
}
@end

 

//JS:
RCTSQLManager.query("SELECT * FROM table", function(result) {
//result == "ret";
});

½ÓÏÂÀ´¿´¿´ËüÊÇÔõÑùʵÏֵġ£

Ä£¿éÅäÖñí

Ê×ÏÈOCÒª¸æËßJSËüÓÐʲôģ¿é£¬Ä£¿éÀïÓÐʲô·½·¨£¬JS²ÅÖªµÀÓÐÕâЩ·½·¨ºó²ÅÓпÉÄÜÈ¥µ÷ÓÃÕâЩ·½·¨¡£ÕâÀïµÄʵÏÖÊÇOCÉú³ÉÒ»·ÝÄ£¿éÅäÖÃ±í´«¸øJS£¬ÅäÖñíÀï°üÀ¨ÁËËùÓÐÄ£¿éºÍÄ£¿éÀï·½·¨µÄÐÅÏ¢¡£Àý£º

{
"remoteModuleConfig": {
"RCTSQLManager": {
"methods": {
"query": {
"type": "remote",
"methodID": 0
}
},
"moduleID": 4
},
...
},
}

OC¶ËºÍJS¶Ë·Ö±ð¸÷ÓÐÒ»¸öbridge£¬Á½¸öbridge¶¼±£´æÁËͬÑùÒ»·ÝÄ£¿éÅäÖÃ±í£¬JSµ÷ÓÃOCÄ£¿é·½·¨Ê±£¬Í¨¹ýbridgeÀïµÄÅäÖñí°ÑÄ£¿é·½·¨×ªÎªÄ£¿éIDºÍ·½·¨ID´«¸øOC£¬OCͨ¹ýbridgeµÄÄ£¿éÅäÖñíÕÒµ½¶ÔÓ¦µÄ·½·¨Ö´ÐÐÖ®£¬ÒÔÉÏÊö´úÂëΪÀý£¬Á÷³Ì´ó¸ÅÊÇÕâÑù£¨ÏȲ»¿¼ÂÇcallback£©£º

ÔÚÁ˽âÕâ¸öµ÷ÓÃÁ÷³Ì֮ǰ£¬ÎÒÃÇÏÈÀ´¿´¿´OCµÄÄ£¿éÅäÖñíʽÔõôÀ´µÄ¡£ÎÒÃÇÔÚн¨Ò»¸öOCÄ£¿éʱ£¬JSºÍOC¶¼²»ÐèҪΪеÄÄ£¿éÊÖ¶¯È¥Ä³¸öµØ·½Ìí¼ÓһЩÅäÖã¬Ä£¿éÅäÖñíÊÇ×Ô¶¯Éú³ÉµÄ£¬Ö»ÒªÏîÄ¿ÀïÓÐÒ»¸öÄ£¿é£¬¾Í»á°ÑÕâ¸öÄ£¿é¼Óµ½ÅäÖñíÉÏ£¬ÄÇÕâ¸öÄ£¿éÅäÖñíÊÇÔõÑù×Ô¶¯Éú³ÉµÄÄØ£¿·ÖÁ½¸ö²½Ö裺

1.È¡ËùÓÐÄ£¿éÀà

ÿ¸öÄ£¿éÀ඼ʵÏÖÁËRCTBridgeModule½Ó¿Ú£¬¿ÉÒÔͨ¹ýruntime½Ó¿Úobjc_getClassList»òobjc_copyClassListÈ¡³öÏîÄ¿ÀïËùÓÐÀ࣬ȻºóÖð¸öÅжÏÊÇ·ñʵÏÖÁËRCTBridgeModule½Ó¿Ú£¬¾Í¿ÉÒÔÕÒµ½ËùÓÐÄ£¿éÀ࣬ʵÏÖÔÚRCTBridgeModuleClassesByModuleID()·½·¨Àï¡£

2.ȡģ¿éÀﱩ¶¸øJSµÄ·½·¨

Ò»¸öÄ£¿éÀï¿ÉÒÔÓкܶ෽·¨£¬Ò»Ð©ÊÇ¿ÉÒÔ±©Â¶¸øJSÖ±½Óµ÷Óõģ¬Ò»Ð©ÊÇ˽ÓеIJ»Ï뱩¶¸øJS£¬ÔõÑù×öµ½ÌáÈ¡ÕâЩ±©Â¶µÄ·½·¨ÄØ£¿ÎÒÄÜÏëµ½µÄ·½·¨ÊǶÔÒª±©Â¶µÄ·½·¨ÃûÖÆ¶¨Ò»Ð©¹æÔò£¬±ÈÈçÓÃRCTExport_×÷Ϊǰ׺£¬È»ºóÓÃruntime·½·¨class_getInstanceMethodÈ¡³öËùÓз½·¨Ãû×Ö£¬ÌáÈ¡ÒÔRCTExport_Ϊǰ׺µÄ·½·¨£¬µ«ÕâÑù×ö¶ñÐĵĵط½ÊÇÿ¸ö·½·¨±ØÐë¼Óǰ׺¡£React NativeÓÃÁËÁíÒ»ÖÖºÚħ·¨ËƵķ½·¨½â¾öÕâ¸öÎÊÌ⣺±àÒëÊôÐÔ__attribute__¡£

ÔÚÉÏÊöÀý×ÓÖÐÎÒÃÇ¿´µ½Ä£¿é·½·¨ÀïÓоä´úÂ룺RCT_EXPORT()£¬Ä£¿éÀïµÄ·½·¨¼ÓÉÏÕâ¸öºê¾Í¿ÉÒÔʵÏÖ±©Â¶¸øJS£¬ÎÞÐèÆäËû¹æÔò£¬ÄÇÕâ¸öºê×öÁËÊ²Ã´ÄØ£¿À´¿´¿´ËüµÄ¶¨Ò壺

#define RCT_EXPORT(JS_name) __attribute__((used, section("__DATA,RCTExport" \
))) static const char *__rct_export_entry__[] = { __func__, #JS_name }

Õâ¸öºêµÄ×÷ÓÃÊÇÓñàÒëÊôÐÔ__attribute__¸ø¶þ½øÖÆÎļþн¨Ò»¸ösection£¬ÊôÓÚ__DATAÊý¾Ý¶Î£¬Ãû×ÖΪRCTExport£¬²¢ÔÚÕâ¸ö¶ÎÀï¼ÓÈ뵱ǰ·½·¨Ãû¡£±àÒëÆ÷ÔÚ±àÒëʱ»áÕÒµ½__attribute__½øÐд¦Àí£¬ÎªÉú³ÉµÄ¿ÉÖ´ÐÐÎļþ¼ÓÈëÏàÓ¦µÄÄÚÈÝ¡£Ð§¹û¿ÉÒÔ´Ólinkmap¿´³öÀ´£º

# Sections:
# Address Size Segment Section
0x100001670 0x000C0180 __TEXT __text
...
0x10011EFA0 0x00000330 __DATA RCTExport
0x10011F2D0 0x00000010 __DATA __common
0x10011F2E0 0x000003B8 __DATA __bss
...

0x10011EFA0 0x00000010 [ 4] -[RCTStatusBarManager setStyle:animated:].__rct_export_entry__
0x10011EFB0 0x00000010 [ 4] -[RCTStatusBarManager setHidden:withAnimation:].__rct_export_entry__
0x10011EFC0 0x00000010 [ 5] -[RCTSourceCode getScriptText:failureCallback:].__rct_export_entry__
0x10011EFD0 0x00000010 [ 7] -[RCTAlertManager alertWithArgs:callback:].__rct_export_entry__
...

 

¿ÉÒÔ¿´µ½¿ÉÖ´ÐÐÎļþÊý¾Ý¶Î¶àÁ˸öRCTExport¶Î£¬ÄÚÈݾÍÊǸ÷¸öÒª±©Â¶¸øJSµÄ·½·¨¡£ÕâЩÄÚÈÝÊÇ¿ÉÒÔÔÚÔËÐÐʱ»ñÈ¡µ½µÄ£¬ÔÚRCTBridge.mµÄRCTExportedMethodsByModuleID()·½·¨Àï»ñÈ¡ÕâЩÄÚÈÝ£¬Ìáȡÿ¸ö·½·¨µÄÀàÃûºÍ·½·¨Ãû£¬¾ÍÍê³ÉÁËÌáȡģ¿éÀﱩ¶¸øJS·½·¨µÄ¹¤×÷¡£

ÕûÌåµÄÄ£¿éÀà/·½·¨ÌáȡʵÏÖÔÚRCTRemoteModulesConfig()·½·¨Àï¡£

µ÷ÓÃÁ÷³Ì

½ÓÏÂÀ´¿´¿´JSµ÷ÓÃOCÄ£¿é·½·¨µÄÏêϸÁ÷³Ì£¬°üÀ¨callback»Øµ÷¡£ÕâʱÐèҪϸ»¯Ò»ÏÂÉÏÊöµÄµ÷ÓÃÁ÷³Ìͼ£º

¿´ÆðÀ´Óе㸴ÔÓ£¬²»¹ýÒ»²½²½ËµÃ÷£¬Ó¦¸ÃºÜÈÝÒ×ŪÇå³þÕû¸öÁ÷³Ì£¬Í¼ÖÐÿ¸öÁ÷³Ì¶¼±êÁËÐòºÅ£¬´Ó·¢Æðµ÷Óõ½Ö´Ðлص÷×ܹ²ÓÐ11¸ö²½Ö裬Ïêϸ˵Ã÷ÏÂÕâЩ²½Ö裺

1.JS¶Ëµ÷ÓÃij¸öOCÄ£¿é±©Â¶³öÀ´µÄ·½·¨¡£

2.°ÑÉÏÒ»²½µÄµ÷Ó÷ֽâΪModuleName,MethodName,arguments£¬ÔÙÈÓ¸øMessageQueue´¦Àí¡£

ÔÚ³õʼ»¯Ê±Ä£¿éÅäÖñíÉϵÄÿһ¸öÄ£¿é¶¼Éú³ÉÁ˶ÔÓ¦µÄremoteModule¶ÔÏ󣬶ÔÏóÀïÒ²Éú³ÉÁ˸úÄ£¿éÅäÖñíÀïÒ»Ò»¶ÔÓ¦µÄ·½·¨£¬ÕâЩ·½·¨Àï¿ÉÒÔÄõ½×ÔÉíµÄÄ£¿éÃû£¬·½·¨Ãû£¬²¢¶Ôcallback½øÐÐһЩ´¦Àí£¬ÔÙÒÆ½»¸øMessageQueue¡£¾ßÌåʵÏÖÔÚBatchedBridgeFactory.jsµÄ_createBridgedModuleÀÕû¸öʵÏÖÇøÇø24ÐдúÂ룬¸ÐÊÜÏÂJSµÄħÁ¦°É¡£

3.ÔÚÕâÒ»²½°ÑJSµÄcallbackº¯Êý»º´æÔÚMessageQueueµÄÒ»¸ö³ÉÔ±±äÁ¿ÀÓÃCallbackID´ú±ícallback¡£ÔÚͨ¹ý±£´æÔÚMessageQueueµÄÄ£¿éÅäÖñí°ÑÉÏÒ»²½´«½øÀ´µÄModuleNameºÍMethodNameתΪModuleIDºÍMethodID¡£

4.°ÑÉÏÊö²½ÖèµÃµ½µÄModuleID,MethodId,CallbackIDºÍÆäËû²ÎÊýargus´«¸øOC¡£ÖÁÓÚ¾ßÌåÊÇÔõô´«µÄ£¬ºóÃæÔÙ˵¡£

5.OC½ÓÊÕµ½ÏûÏ¢£¬Í¨¹ýÄ£¿éÅäÖñíÄõ½¶ÔÓ¦µÄÄ£¿éºÍ·½·¨¡£

ʵ¼ÊÉÏÄ£¿éÅäÖñíÒѾ­¾­¹ý´¦ÀíÁË£¬¸úJSÒ»Ñù£¬ÔÚ³õʼ»¯Ê±OCÒ²¶ÔÄ£¿éÅäÖñíÉϵÄÿһ¸öÄ£¿éÉú³ÉÁ˶ÔÓ¦µÄʵÀý²¢»º´æÆðÀ´£¬Ä£¿éÉϵÄÿһ¸ö·½·¨Ò²¶¼Éú³ÉÁ˶ÔÓ¦µÄRCTModuleMethod¶ÔÏó£¬ÕâÀïͨ¹ýModuleIDºÍMethodIDÈ¡µ½¶ÔÓ¦µÄModuleʵÀýºÍRCTModuleMethodʵÀý½øÐе÷Ó᣾ßÌåʵÏÖÔÚ_handleRequestNumber:moduleID:methodID:params:¡£

6.RCTModuleMethod¶ÔJS´«¹ýÀ´µÄÿһ¸ö²ÎÊý½øÐд¦Àí¡£

RCTModuleMethod¿ÉÒÔÄõ½OCÒªµ÷ÓõÄÄ¿±ê·½·¨µÄÿ¸ö²ÎÊýÀàÐÍ£¬´¦ÀíJSÀàÐ͵½Ä¿±êÀàÐ͵Äת»»£¬ËùÓÐJS´«¹ýÀ´µÄÊý×Ö¶¼ÊÇNSNumber£¬ÕâÀï»áת³É¶ÔÓ¦µÄint/long/doubleµÈÀàÐÍ£¬¸üÖØÒªµÄÊÇ»áΪblockÀàÐͲÎÊýµÄÉú³ÉÒ»¸öblock¡£

ÀýÈç-(void)select:(int)index response:(RCTResponseSenderBlock)callback Õâ¸ö·½·¨£¬Äõ½Á½¸ö²ÎÊýµÄÀàÐÍΪint,block£¬JS´«¹ýÀ´µÄÁ½¸ö²ÎÊýÀàÐÍÊÇNSNumber,NSString(CallbackID)£¬Õâʱ»á°ÑNSNumberתΪint£¬NSString(CallbackID)תΪһ¸öblock£¬blockµÄÄÚÈÝÊǰѻص÷µÄÖµºÍCallbackID´«»Ø¸øJS¡£

ÕâЩ²ÎÊý×é×°Íê±Ïºó£¬Í¨¹ýNSInvocation¶¯Ì¬µ÷ÓÃÏàÓ¦µÄOCÄ£¿é·½·¨¡£

7.OCÄ£¿é·½·¨µ÷ÓÃÍִ꣬ÐÐblock»Øµ÷¡£

8.µ÷Óõ½µÚ6²½ËµÃ÷µÄRCTModuleMethodÉú³ÉµÄblock¡£

9.blockÀï´ø×ÅCallbackIDºÍblock´«¹ýÀ´µÄ²ÎÊýÈ¥µ÷JSÀïMessageQueueµÄ·½·¨invokeCallbackAndReturnFlushedQueue¡£

10.MessageQueueͨ¹ýCallbackIDÕÒµ½ÏàÓ¦µÄJS callback·½·¨¡£

11.µ÷ÓÃcallback·½·¨£¬²¢°ÑOC´ø¹ýÀ´µÄ²ÎÊýÒ»Æð´«¹ýÈ¥£¬Íê³É»Øµ÷¡£

Õû¸öÁ÷³Ì¾ÍÊÇÕâÑù£¬¼òµ¥¸ÅÀ¨Ï£¬²î²»¶à¾ÍÊÇ£ºJSº¯Êýµ÷ÓÃתModuleID/MethodID -> callbackתCallbackID -> OC¸ù¾ÝIDÄõ½·½·¨ -> ´¦Àí²ÎÊý -> µ÷ÓÃOC·½·¨ -> »Øµ÷CallbackID -> JSͨ¹ýCallbackIDÄõ½callbackÖ´ÐÐ

ʼþÏìÓ¦

ÉÏÊöµÚ4²½ÁôÏÂÒ»¸öÎÊÌ⣬JSÊÇÔõÑù°ÑÊý¾Ý´«¸øOC£¬ÈÃOCÈ¥µ÷ÏàÓ¦·½·¨µÄ£¿

´ð°¸ÊÇͨ¹ý·µ»ØÖµ¡£JS²»»áÖ÷¶¯´«µÝÊý¾Ý¸øOC£¬ÔÚµ÷OC·½·¨Ê±£¬»áÔÚÉÏÊöµÚ4²½°ÑModuleID,MethodIDµÈÊý¾Ý¼Óµ½Ò»¸ö¶ÓÁÐÀµÈOC¹ýÀ´µ÷JSµÄÈÎÒâ·½·¨Ê±£¬ÔÙ°ÑÕâ¸ö¶ÓÁзµ»Ø¸øOC£¬´ËʱOCÔÙÖ´ÐÐÕâ¸ö¶ÓÁÐÀïÒªµ÷Óõķ½·¨¡£

Ò»¿ªÊ¼²»Ã÷°×£¬Éè¼Æ³ÉJSÎÞ·¨Ö±½Óµ÷ÓÃOC£¬ÐèÒªÔÚOCÈ¥µ÷JSʱ²Åͨ¹ý·µ»ØÖµ´¥·¢µ÷Óã¬Õû¸ö³ÌÐò»¹ÄÜÅܵÃͨÂ𡣺óÀ´ÏëÏë´¿native¿ª·¢ÀïµÄʼþÏìÓ¦»úÖÆ£¬¾ÍÓеãÀí½âÁË¡£native¿ª·¢Àʲôʱºò»áÖ´ÐдúÂ룿ֻÔÚÓÐʼþ´¥·¢µÄʱºò£¬Õâ¸öʼþ¿ÉÒÔÊÇÆô¶¯Ê¼þ£¬´¥Ãþʼþ£¬timerʼþ£¬ÏµÍ³Ê¼þ£¬»Øµ÷ʼþ¡£¶øÔÚReact NativeÀÕâЩʼþ·¢ÉúʱOC¶¼»áµ÷ÓÃJSÏàÓ¦µÄÄ£¿é·½·¨È¥´¦Àí£¬´¦ÀíÍêÕâЩʼþºóÔÙÖ´ÐÐJSÏëÈÃOCÖ´Ðеķ½·¨£¬¶øÃ»ÓÐʼþ·¢ÉúµÄʱºò£¬ÊDz»»áÖ´ÐÐÈκδúÂëµÄ£¬Õâ¸únative¿ª·¢ÀïʼþÏìÓ¦»úÖÆÊÇÒ»Öµġ£

˵µ½OCµ÷ÓÃJS£¬ÔÙ²¹³äһϣ¬Êµ¼ÊÉÏÄ£¿éÅäÖñí³ýÁËÓÐÉÏÊöOCµÄÄ£¿éremoteModulesÍ⣬»¹±£´æÁËJSÄ£¿élocalModules£¬OCµ÷JSijЩģ¿éµÄ·½·¨Ê±£¬Ò²ÊÇͨ¹ý´«µÝModuleIDºÍMethodIDÈ¥µ÷Óõ쬶¼»á×ßµ½-enqueueJSCall:args:·½·¨°ÑÁ½¸öIDºÍ²ÎÊý´«¸øJSµÄBatchedBridge.callFunctionReturnFlushedQueue£¬¸úJSµ÷OCÔ­Àí²î²»¶à£¬¾Í²»ÔÙ׸ÊöÁË¡£

   
2348 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì