让你的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;

目录
相关文章
|
10月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
976 4
|
5月前
|
JavaScript 前端开发 API
|
10月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端框架
【10月更文挑战第34天】在数字化时代,后端开发如同一座桥梁,连接着用户界面与数据处理的两端。本文将通过Node.js这一轻量级、高效的平台,带领读者领略后端框架的魅力。我们将从基础概念出发,逐步深入到实战应用,最后探讨如何通过代码示例来巩固学习成果,使读者能够在理论与实践之间架起自己的桥梁。
|
7月前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
787 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
7月前
|
JavaScript Shell C#
多种脚本批量下载 Docker 镜像:Shell、PowerShell、Node.js 和 C#
本项目提供多种脚本(Shell、PowerShell、Node.js 和 C#)用于批量下载 Docker 镜像。配置文件 `docker-images.txt` 列出需要下载的镜像及其标签。各脚本首先检查 Docker 是否安装,接着读取配置文件并逐行处理,跳过空行和注释行,提取镜像名称和标签,调用 `docker pull` 命令下载镜像,并输出下载结果。使用时需创建配置文件并运行相应脚本。C# 版本需安装 .NET 8 runtime。
408 3
|
6月前
|
iOS开发 开发者 Windows
uniapp云打包ios应用证书的获取方法,生成指南
打包用到的一共两个文件,一个是p12格式的私钥证书,一个是证书profile文件。其中生成p12证书的时候,按照官网的教程,是需要MAC电脑来协助做的,主要是生成一些csr文件和导出p12证书等。其实这些步骤也可以借助一些其他的工具来实现,不一定使用mac电脑,用windows电脑也可以创建。
870 0
|
9月前
|
数据采集 人工智能 自然语言处理
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
Midscene.js 是一款基于 AI 技术的 UI 自动化测试框架,通过自然语言交互简化测试流程,支持动作执行、数据查询和页面断言,提供可视化报告,适用于多种应用场景。
2404 1
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
|
10月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
10月前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
10月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
205 2