個(gè)人覺(jué)得學(xué)習(xí)iOS方面的知識(shí),還得需要看蘋(píng)果的開(kāi)發(fā)文檔,網(wǎng)上的教程還是比較片面,只能交給你怎么用,但是原理很少講。這篇文章我主要講的是文檔里比較難理解的東西。 Demo地址:JavaScriptCoreTest
JSExport
The JSExport protocol provides a declarative way to export Objective-C instance classes and their instance methods, class methods, and properties to JavaScript code.
JSExport提供了一個(gè)聲明的方式,來(lái)把OC的類(lèi),實(shí)例方法,類(lèi)方法,屬性這四方面暴露給JavaScript。這樣一來(lái)JavaScript就可以調(diào)用OC的類(lèi)方法或init方法創(chuàng)建實(shí)例,給屬性賦值,調(diào)用實(shí)例的方法等。
Exporting Objective-C Objects to JavaScript
When you create a JavaScript value from an instance of an Objective-C class, and the JSValue class does not specify a copying convention, JavaScriptCore creates a JavaScript wrapper object. (For certain classes, JavaScriptCore automatically copies values to the appropriate JavaScript type; for example, NSString instances become JavaScript strings.)
JSValue是個(gè)什么東西呢?JSValue是對(duì)JavaScript事物的引用,我們知道JavaScript所有事物都是對(duì)象,那么JavaScriptCore就用JSValue來(lái)作為JavaScript value的標(biāo)識(shí)。JSValue類(lèi)可以用來(lái)轉(zhuǎn)換OC與JavaScript的basic values(number, string等)來(lái)達(dá)到pass data的目的。比如說(shuō)OC需要一個(gè)NSString對(duì)象,現(xiàn)在你知道了這個(gè)對(duì)象的JSValue值,那么可以調(diào)用- toString方法轉(zhuǎn)換成NSString對(duì)象。如果你要傳給JavaScriptCore一個(gè)JSValue,同理你調(diào)用[JSValue valueWithObject:inContext]可以將NSString對(duì)象a轉(zhuǎn)換成JSValue value。
當(dāng)你創(chuàng)建OC object的JSValue時(shí),JSValue類(lèi)并不能指定拷貝的約定,耳JavaScriptCore可以創(chuàng)建一個(gè)JavaScript包裝對(duì)象來(lái)實(shí)現(xiàn)value的copy。
In JavaScript, inheritance is supported via a chain of prototype objects. For each Objective-C class you export, JavaScriptCore creates a prototype within the enclosing JavaScript context (a JSContext object). For the NSObject class, the prototype object is the JavaScript context's Object prototype. For all other Objective-C classes, JavaScriptCore creates a prototype object whose internal [Prototype] property points to the prototype property created for the Objective-C class's superclass. As such, the prototype chain for a JavaScript wrapper object reflects the wrapped Objective-C type's inheritance hierarchy.
JavaScript不是面向?qū)ο笳Z(yǔ)言,而是基于對(duì)象語(yǔ)言。所以其就沒(méi)有類(lèi),繼承,多態(tài),封裝等屬性。但是JavaScript可以使用a chain of prototype objects(原始對(duì)象響應(yīng)鏈)的方式實(shí)現(xiàn)繼承等。具體JavaScript如何實(shí)現(xiàn)自定義類(lèi)和繼承,可以上網(wǎng)查。我們的JavaScriptCore會(huì)為我們的NSObject或其他OC類(lèi)創(chuàng)建一個(gè)prototype object來(lái)實(shí)現(xiàn)OC自定義類(lèi)對(duì)象轉(zhuǎn)換為JS自定義類(lèi)對(duì)象。
Exposing Objective-C Methods and Properties to JavaScript
By default, no methods or properties of the Objective-C class are exposed to JavaScript; instead, you must choose methods and properties to export. For each protocol that a class conforms to, if the protocol incorporates the JSExport protocol, then JavaScriptCore interprets that protocol as a list of methods and properties to be exported to JavaScript.
For each instance method exported, JavaScriptCore creates a corresponding JavaScript function as a property of the prototype object. For each Objective-C property exported, JavaScriptCore creates a JavaScript accessor property on the prototype. For each class method exported, JavaScriptCore creates a JavaScript function on the constructor object. For example, Listing 1 and Listing 2 illustrate adoption of the JSExport protocol and the API presented by an exported class in JavaScript.
在JavaScript中,因?yàn)樗惺挛锒际菍?duì)象,所以function(函數(shù))也是一個(gè)對(duì)象。在JavaScript code里有這樣語(yǔ)句就不奇怪了:var calSum = function() {...};
For example, Listing 1 and Listing 2 illustrate adoption of the JSExport protocol and the API presented by an exported class in JavaScript.
Listing 1
Exporting an Objective-C Class to JavaScript
@protocol MyPointExports <JSExport>
@property double x;
@property double y;
- (NSString *)description;
- (instancetype)initWithX:(double)x y:(double)y;
+ (MyPoint *)makePointWithX:(double)x y:(double)y;
@end
@interface MyPoint : NSObject <MyPointExports>
- (void)myPrivateMethod; // Not in the MyPointExports protocol, so not visible to JavaScript code.
@end
@implementation MyPoint
// ...
@end
Listing 2
Using an Exported Objective-C Class from JavaScript
// Objective-C properties become fields.
point.x;
point.x = 10;
// Objective-C instance methods become functions.
point.description();
// Objective-C initializers can be called with constructor syntax.
var p = MyPoint(1, 2);
// Objective-C class methods become functions on the constructor object.
var q = MyPoint.makePointWithXY(0, 0);
Bug:OC的initializers可以用constructor syntax.(構(gòu)造函數(shù))來(lái)實(shí)現(xiàn),上面的代碼var p = MyPoint(1, 2)確實(shí)也是這樣。可是我自己在demo中用類(lèi)似的方式根本不會(huì)創(chuàng)建實(shí)例p成功,后來(lái)網(wǎng)上查了下這樣寫(xiě)才是正確的。給自己的initializers打了斷點(diǎn),確實(shí)是JS調(diào)用了。上面代碼就var p = MyPoint(1, 2)有問(wèn)題,其他類(lèi)方法,屬性賦值,實(shí)例方法調(diào)用是沒(méi)問(wèn)題的。
var p = new MyPoint(1, 2);