让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(二)

简介: 让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解

四、深入JSContext类


   看到这,你已经学会最基础的OC与JS互相问好(交互)。下面我们再来深入看下JSContext中的属性和方法。


   创建JSContext对象有如下两种方式:


//创建一个新的JS运行环境

- (instancetype)init;

//创建一个新的JS运行环境 并关联到某个虚拟机对象上

- (instancetype)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;

   执行JS代码有如下两个方法:


//执行JS代码 结果将封装成JSValue对象返回

- (JSValue *)evaluateScript:(NSString *)script;

//作用同上

- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL NS_AVAILABLE(10_10, 8_0);

   下面的属性和方法可以获取到JS运行环境中的一些信息:


//当前的JS运行环境 当JS调用OC方法时,在OC方法中可以用此方法获取到JS运行环境

+ (JSContext *)currentContext;

//获取当前执行的JS函数,当JS调用OC方法时,在OC方法中可以用此方法获取到执行的函数

+ (JSValue *)currentCallee;

//获取当前执行的JS函数中的this指向的对象

+ (JSValue *)currentThis;

//获取当前执行函数的参数列表,当JS调用OC方法时,在OC方法中可以用此方法获取到执行的函数的参数列表

+ (NSArray *)currentArguments;

//获取当前JS运行环境的全局对象

@property (readonly, strong) JSValue *globalObject;

//当运行的JavaScript代码抛出了未捕获的异常时,这个属性会被赋值为抛出的异常

@property (strong) JSValue *exception;

//设置为一个异常捕获的block,如果异常被此block捕获,exception属性就不再被赋值了

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

//当前运行环境所关联的虚拟机

@property (readonly, strong) JSVirtualMachine *virtualMachine;

//当前运行环境名称

@property (copy) NSString *name;

//获取当前JS运行环境全局对象上的某个属性

- (JSValue *)objectForKeyedSubscript:(id)key;

//设置当前JS运行环境全局对象上的属性

- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;

//将C语言环境的JS运行环境转换为OC环境的JS运行环境

+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)jsGlobalContextRef;

//C语言环境的JS运行上下文

@property (readonly) JSGlobalContextRef JSGlobalContextRef;

五、深入JSValue类


   JSValue是JavaScript与Objective-C之间的数据桥梁。在Objective-C中调用JS脚本或者JS调用OC方法都可以使用JSValue来传输数据。其中属性和方法示例如下:


//所对应的JS运行环境

@property (readonly, strong) JSContext *context;

//在指定的JS运行环境中创建一个JSValue对象

+ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context;

//创建布尔值

+ (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context;

//创建浮点值

+ (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context;

//创建32位整型值

+ (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context;

//创建32位无符号整形值

+ (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context;

//创建空的JS对象

+ (JSValue *)valueWithNewObjectInContext:(JSContext *)context;

//创建空的JS数组

+ (JSValue *)valueWithNewArrayInContext:(JSContext *)context;

//创建JS正则对象

+ (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context;

//创建JS错误信息

+ (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context;

//创建JS null值

+ (JSValue *)valueWithNullInContext:(JSContext *)context;

//创建JS undefined值

+ (JSValue *)valueWithUndefinedInContext:(JSContext *)context;

JavaScript中的数据类型和Objective-C的数据类型还是有着很大的差异,其中对应关系如下:


Objective-C  JavaScript

nil undefined

NSNull null

NSString string

NSNumber number boolean

NSDictionary    Object

NSArray Array

NSDate Date  

Block Function

id Object

Class Object

下面这些方法可以将JSValue值转换为Objective-C中的数据类型:


//将JSValue转换为OC对象

- (id)toObject;

//将JSValue转换成特定OC类的对象

- (id)toObjectOfClass:(Class)expectedClass;

//将JSValue转换成布尔值

- (BOOL)toBool;

//将JSValue转换成浮点值

- (double)toDouble;

//将JSValue转换成32位整型值

- (int32_t)toInt32;

//将JSValue转换成32位无符号整型值

- (uint32_t)toUInt32;

//将JSValue转换成NSNumber值

- (NSNumber *)toNumber;

//将JSValue转换成NSString值

- (NSString *)toString;

//将JSValue转换成NSDate值

- (NSDate *)toDate;

//将JSValue转换成NSArray值

- (NSArray *)toArray;

//将JSValue转换成NSDictionary值

- (NSDictionary *)toDictionary;

//获取JSValue对象中某个属性的值

- (JSValue *)valueForProperty:(NSString *)property;

//设置JSValue对象中某个属性的值

- (void)setValue:(id)value forProperty:(NSString *)property;

//删除JSValue对象中的某个属性

- (BOOL)deleteProperty:(NSString *)property;

//判断JSValue对象中是否包含某个属性

- (BOOL)hasProperty:(NSString *)property;

//定义JSValue中的某个属性 这个方法和JavaScript中Object构造函数的defineProperty方法一致

/*

第2个参数设置此属性的描述信息 可以设置的键值如下:

NSString * const JSPropertyDescriptorWritableKey;//设置布尔值 是否可写

NSString * const JSPropertyDescriptorEnumerableKey;//设置布尔值 是否可枚举

NSString * const JSPropertyDescriptorConfigurableKey;//设置布尔值 是否可配置

NSString * const JSPropertyDescriptorValueKey;//设置此属性的值

NSString * const JSPropertyDescriptorGetKey;//设置此属性的get方法

NSString * const JSPropertyDescriptorSetKey;//设置此属性的set方法

以上set、get方法的键和value、可写性的键不能同时存在,其语法是JavaScript保持一致

*/

- (void)defineProperty:(NSString *)property descriptor:(id)descriptor;

//获取JS数组对象某个下标的值

- (JSValue *)valueAtIndex:(NSUInteger)index;

//设置JS数组对象某个下标的值

- (void)setValue:(id)value atIndex:(NSUInteger)index;

//判断此对象是否为undefined

@property (readonly) BOOL isUndefined;

//判断此对象是否为null

@property (readonly) BOOL isNull;

//判断此对象是否为布尔值

@property (readonly) BOOL isBoolean;

//判断此对象是否为数值

@property (readonly) BOOL isNumber;

//判断此对象是否为字符串

@property (readonly) BOOL isString;

//判断此对象是否为object对象

@property (readonly) BOOL isObject;

//判断此对象是否为数组

@property (readonly) BOOL isArray;

//判断此对象是否为日期对象

@property (readonly) BOOL isDate;

//比较两个JSValue是否全相等 对应JavaScript中的===

- (BOOL)isEqualToObject:(id)value;

//比较两个JSValue对象的值是否相等 对应JavaScript中的==

- (BOOL)isEqualWithTypeCoercionToObject:(id)value;

//判断某个对象是否在当前对象的原型链上

- (BOOL)isInstanceOf:(id)value;

//如果JSValue是Function对象 可以调用此方法 和JavaScript中的call方法一致

- (JSValue *)callWithArguments:(NSArray *)arguments;

//如果JSValue是一个构造方法对象 可以调用此方法 和JavaScript中使用new关键字一致

- (JSValue *)constructWithArguments:(NSArray *)arguments;

//用此对象进行函数的调用 当前对象会被绑定到this中

- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments;

//将CGPoint转换为JSValue对象

+ (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context;

//将NSRange转换为JSValue对象

+ (JSValue *)valueWithRange:(NSRange)range inContext:(JSContext *)context;

//将CGRect转换为JSValue对象

+ (JSValue *)valueWithRect:(CGRect)rect inContext:(JSContext *)context;

//将CGSize转换为JSValue对象

+ (JSValue *)valueWithSize:(CGSize)size inContext:(JSContext *)context;

//转换成CGPoint数据

- (CGPoint)toPoint;

//转换成NSRange数据

- (NSRange)toRange;

//转换成CGRect数据

- (CGRect)toRect;

//转换为CGSize数据

- (CGSize)toSize;

//将C风格的JSValueRef对象转换为JSValue对象

+ (JSValue *)valueWithJSValueRef:(JSValueRef)value inContext:(JSContext *)context;

其实在JavaScriptCore框架中还有一个JSManagerValue类,这个的主要作用是管理内存。虽然我们在编写Objective-C代码时有强大的自动引用技术(ARC技术),我们一般无需关心对象的内存问题,在编写JavaScript代码时也有强大的垃圾回收机制(这种机制下甚至连循环引用都不是问题),但是在OC和JS混合开发时,就很容易出现问题了,比如一个JS垃圾回收机制释放掉的对象OC中却还在用,反过来也是一样。JSManagerValue对JSValue进行了一层包装,它可以保证在适合时候使用这个对象时对象都不会被释放,其中方法如下:


//创建JSVlaue对象的包装JSManagerValue

+ (JSManagedValue *)managedValueWithValue:(JSValue *)value;

+ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner;

- (instancetype)initWithValue:(JSValue *)value;

//获取所包装的JSValue对象

@property (readonly, strong) JSValue *value;

目录
相关文章
|
29天前
|
Web App开发 JavaScript 前端开发
构建高效后端服务:Node.js与Express框架的实战指南
【9月更文挑战第6天】在数字化时代的潮流中,后端开发作为支撑现代Web和移动应用的核心,其重要性不言而喻。本文将深入浅出地介绍如何使用Node.js及其流行的框架Express来搭建一个高效、可扩展的后端服务。通过具体的代码示例和实践技巧,我们将探索如何利用这两个强大的工具提升开发效率和应用性能。无论你是后端开发的新手还是希望提高现有项目质量的老手,这篇文章都将为你提供有价值的见解和指导。
|
2月前
|
物联网 区块链 vr&ar
未来已来:探索区块链、物联网与虚拟现实技术的融合与应用安卓与iOS开发中的跨平台框架选择
【8月更文挑战第30天】在科技的巨轮下,新技术不断涌现,引领着社会进步。本文将聚焦于当前最前沿的技术——区块链、物联网和虚拟现实,探讨它们各自的发展趋势及其在未来可能的应用场景。我们将从这些技术的基本定义出发,逐步深入到它们的相互作用和集成应用,最后展望它们如何共同塑造一个全新的数字生态系统。
|
2月前
|
存储 JavaScript NoSQL
构建高效Web应用:使用Node.js和Express框架
【8月更文挑战第30天】本文将引导你了解如何使用Node.js和Express框架快速搭建一个高效的Web应用。通过实际的代码示例,我们将展示如何创建一个简单的API服务,并讨论如何利用中间件来增强应用功能。无论你是新手还是有经验的开发者,这篇文章都将为你提供有价值的见解。
|
7天前
|
Web App开发 JavaScript 前端开发
构建高效Web应用:Node.js与Express框架的深度整合
【9月更文挑战第28天】在现代Web开发领域,Node.js和Express框架的结合已成为打造高性能、易扩展应用的黄金组合。本文将深入探讨如何利用这一技术栈优化Web应用架构,提供具体实践指导,并分析其性能提升的内在机制。通过代码示例,我们将展示从基础搭建到高级功能的实现过程,旨在为开发者提供一条清晰的学习路径,以实现技术升级和项目效率的双重提升。
20 3
|
10天前
|
前端开发 JavaScript API
React、Vue.js 和 Angular前端三大框架对比与选择
前端框架是用于构建用户界面的工具和库,它提供组件化结构、数据绑定、路由管理和状态管理等功能,帮助开发者高效地创建和维护 web 应用的前端部分。常见的前端框架如 React、Vue.js 和 Angular,能够提高开发效率并促进团队协作。
26 4
|
12天前
|
JavaScript 前端开发
常用的 JavaScript 框架和库
常用的 JavaScript 框架和库
13 6
|
9天前
|
iOS开发 开发者 UED
探索iOS应用开发中的SwiftUI框架
【9月更文挑战第26天】 在iOS开发的海洋中,SwiftUI犹如一艘现代的快艇,引领着开发者们驶向更加高效与直观的编程体验。本文将带你领略SwiftUI的魅力,从其设计理念到实际应用,我们将一步步揭开它如何简化界面构建过程的面纱。通过对比传统方式,你将看到SwiftUI如何让代码变得像诗一样优美,同时保持强大的功能性和灵活性。准备好让你的iOS开发技能加速升级,一起驾驭这股新潮流吧!
|
12天前
|
前端开发 JavaScript 开发者
React 和 Vue.js 框架的区别是什么?
React 和 Vue.js 框架的区别是什么?
|
14天前
|
前端开发 iOS开发 开发者
探索iOS开发中的SwiftUI框架
【9月更文挑战第21天】在iOS应用开发的广阔天地中,SwiftUI框架如一股清新之风,为开发者带来了声明式语法的便捷与高效。本文将深入探讨SwiftUI的核心概念、布局方式及数据绑定机制,同时通过实例演示如何运用SwiftUI构建用户界面,旨在引领读者领略SwiftUI的魅力,并激发其对iOS开发新趋势的思考与实践。
33 6
|
13天前
|
前端开发 JavaScript Java
JavaScript的运行原理
JavaScript 的运行原理包括代码输入、解析、编译、执行、内存管理和与浏览器交互几个步骤。当打开网页时,浏览器加载 HTML、CSS 和 JavaScript 文件,并通过 JavaScript 引擎将其解析为抽象语法树(AST)。接着,引擎将 AST 编译成字节码或机器码,并在执行阶段利用事件循环机制处理异步操作,确保单线程的 JavaScript 能够高效运行。同时,JavaScript 引擎还负责内存管理和垃圾回收,以减少内存泄漏。通过与 DOM 的交互,JavaScript 实现了动态网页效果,提供了灵活且高效的开发体验。
下一篇
无影云桌面