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

目录
相关文章
|
2月前
|
搜索推荐 数据管理 定位技术
iOS应用开发中有多种主流框架
iOS应用开发中有多种主流框架
230 60
|
2月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
235 4
|
28天前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
120 66
|
2月前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
41 2
|
2月前
|
iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第39天】在苹果的生态系统中,SwiftUI框架以其声明式语法和易用性成为开发者的新宠。本文将深入SwiftUI的核心概念,通过实际案例展示如何利用这一框架快速构建用户界面,并探讨其对iOS应用开发流程的影响。
|
2月前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
2月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
76 1
|
3月前
|
移动开发 网络协议 小程序
基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v9.1版已发布
RainbowChat是一套基于开源IM聊天框架 MobileIMSDK 的产品级移动端IM系统。RainbowChat源于真实运营的产品,解决了大量的屏幕适配、细节优化、机器兼容问题
74 5
|
2月前
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
3月前
|
Swift iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】在苹果生态系统中,SwiftUI的引入无疑为iOS应用开发带来了革命性的变化。本文将通过深入浅出的方式,带领读者了解SwiftUI的基本概念、核心优势以及如何在实际项目中运用这一框架。我们将从一个简单的例子开始,逐步深入到更复杂的应用场景,让初学者能够快速上手,同时也为有经验的开发者提供一些深度使用的技巧和策略。
62 1