ios7 JavaScriptCore.framework

基于Python的Booking酒店数据爬虫实战:最新技术与完整代码解析 本文将详细介绍如何使用Python构建一个高效的Booking酒店数据爬虫,涵盖从基础爬取到高级反反爬技术的完整实现。我们将使用最新的Python爬虫技术栈,包括requests-html、Playwright、智能代理轮换等技术,并提供完整的可运行代码示例。文章将深入探讨爬虫的各个组成部分,包括数据提取、存储、反反爬策略以及性能优化等方面。关键词:Python爬虫、Booking数据采集、反反爬技术、Playwright、数据存储。 阅读详情

这个框架其实只是基于webkit中以C/C++实现的JavaScriptCore的一个包装,在旧版本iOS开发中,很多开发者也会自行将webkit的库引入项目编译使用。不过虽然iOS7把它当成了标准库,可惜目前,我还没有在Apple Developer中找到像之前文章中收集的那样的官方文档介绍这个框架的具体使用方法。

好在还可以在Xcode中找到头文件,而且里面的注释对每个类和方法的功能写得还算清楚,再结合网上仅有的几篇文章的介绍,我也在此简单入门一下JavaScriptCore。更多细节还待开发过程中发现。

JavaScriptCore中的类
JavaScriptCore_Head
在项目中引入JavaScriptCore后,链到头文件中,除了大段的Copyright注释可以看到里面只要引入了5个文件,每个文件里都定义跟文件名对应的类:

JSContext
JSValue
JSManagedValue
JSVirtualMachine
JSExport
虽说代码中的注释介绍的也比较详细了,但是如同一图顶万言,对程序员来说代码更有说服力。本文就先来说说这些类相对比较好理解但又很常用的JSContext和JSValue以及它们方法的使用方式和效果。

JSContext和JSValue
JSVirtualMachine为JavaScript的运行提供了底层资源,JSContext就为其提供着运行环境,通过- (JSValue )evaluateScript:(NSString )script;方法就可以执行一段JavaScript脚本,并且如果其中有方法、变量等信息都会被存储在其中以便在需要的时候使用。而JSContext的创建都是基于JSVirtualMachine:- (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;,如果是使用- (id)init;进行初始化,那么在其内部会自动创建一个新的JSVirtualMachine对象然后调用前边的初始化方法。

JSValue则可以说是JavaScript和Object-C之间互换的桥梁,它提供了多种方法可以方便地把JavaScript数据类型转换成Objective-C,或者是转换过去。其一一对应方式可见下表:

下面通过一些简单的Demo来演示:

1. 基本类型转换

JSContext *context = [[JSContext alloc] init];
JSValue *jsVal = [context evaluateScript:@"21+7"];
int iVal = [jsVal toInt32];
NSLog(@"JSValue: %@,int: %d", jsVal, iVal);

结果如下:
这里写图片描述
js变量存储到JSContext中,可以通过下边取得。

2. 数组类型

JSContext *context = [[JSContext alloc] init];
[context evaluateScript:@"var arr = [21, 7, 'lile.com'];"];
JSValue *jsArr = context[@"arr"];
NSLog(@"JS Array:%@;Length:%@", jsArr, jsArr[@"length"]);

jsArr[1] = @"blog";
jsArr[7] = @7;
NSLog(@"JS Array:%@;Length:%d", jsArr, [jsArr[@"length"] toInt32]);

NSArray *nsArr = [jsArr toArray];
NSLog(@"NSArray:%@", nsArr);

结果截图:
这里写图片描述

通过输出结果很容易看出代码成功把数据从Objective-C赋到了JavaScript数组上,而且JSValue是遵循JavaScript的数组特性:无下标越位,自动延展数组大小。并且通过JSValue还可以获取JavaScript对象上的属性,比如例子中通过”length”就获取到了JavaScript数组的长度。在转成NSArray的时候,所有的信息也都正确转换了过去。

3. 方法的转换

各种数据类型可以转换,Objective-C的Block也可以传入JSContext中当做JavaScript的方法使用。比如在前端开发中常用的log方法,虽然JavaScritpCore没有自带(毕竟不是在网页上运行的,自然不会有window、document、console这些类了),仍然可以定义一个Block方法来调用NSLog来模拟:

JSContext *context = [[JSContext alloc] init];
context[@"log"] = ^(){
    NSLog(@"**********Begin Log**********");

    NSArray *args = [JSContext currentArguments];
    for (JSValue *jsVal in args) {
        NSLog(@"%@", jsVal);
    }
    JSValue *this = [JSContext currentThis];
    NSLog(@"this:%@", this);

   NSLog(@"**********End Log**********");
};

[context evaluateScript:@"log('ider', [7, 21], {hello:'world', js:100});"];

结果如下:
这里写图片描述

通过Block成功的在JavaScript调用方法回到了Objective-C,而且依然遵循JavaScript方法的各种特点,比如方法参数不固定。也因为这样,JSContext提供了类方法来获取参数列表(+ (JSContext *) currentArguments;)和当前调用该方法的对象(+ (JSValue *)currentThis)。对于”this”,输出的内容是GlobalObject,这也是JSContext对象方法- (JSValue *)globalObject;所返回的内容。因为我们知道在JavaScript里,所有全局变量和方法其实都是一个全局变量的属性,在浏览器中是window,在JavaScriptCore是什么就不得而知了。

Block可以传入JSContext作方法,但是JSValue没有toBlock方法来把JavaScript方法变成Block在Objetive-C中使用。毕竟Block的参数个数和类型以及返回类型都是固定的。虽然不能把方法提取出来,但是JSValue提供了- (JSValue *)callWithArguments:(NSArray *)arguments;方法可以反过来将参数传进去来调用方法。

JSContext *context = [[JSContext alloc] init];
[context evaluateScript:@"function add(a, b) {return a + b;}"];
JSValue *add = context[@"add"];
NSLog(@"Func:%@", add);

JSValue *sum = [add callWithArguments:@[@(7), @(21)]];
NSLog(@"Sum:%d",[sum toInt32]);

结果如下:
这里写图片描述

JSValue还提供- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments;让我们可以直接简单地调用对象上的方法。只是如果定义的方法是全局函数,那么很显然应该在JSContext的globalObject对象上调用该方法;如果是某JavaScript对象上的方法,就应该用相应的JSValue对象调用。

4. 异常处理

Objective-C的异常会在运行时被Xcode捕获,而在JSContext中执行的JavaScript如果出现异常,只会被JSContext捕获并存储在exception属性上,而不会向外抛出。时时刻刻检查JSContext对象的exception是否不为nil显然不合适,更合理的方式是给JSContext对象设置exceptionHandler,它接受的是^(JSContext *context, JSValue *exceptionValue)形式的Block。其默认值就是将传入的exceptionValue赋给传入的context的exception属性:

^(JSContext *context, JSValue *exceptionValue) {
    context.exception = exceptionValue;
};

我们也可以给exceptionHandler赋予新的Block以便在JavaScript运行发生异常的时候我们可以立即知道:

JSContext *context = [[JSContext alloc] init];
context.exceptionHandler = ^(JSContext *con, JSValue *exception) {
    NSLog(@"%@", exception);
    con.exception = exception;
};

结果如下:
这里写图片描述

5. 使用Block时的注意事项

从之前的例子和介绍应该有体会到Block在JavaScriptCore中起到的强大作用,它在JavaScript和Objective-C之间的转换 建立起更多的桥梁,让互通更方便。但是要注意的是无论是把Block传给JSContext对象让其变成JavaScript方法,还是把它赋给exceptionHandler属性,在Block内都不要直接使用其外部定义的JSContext对象或者JSValue,应该将其当做参数传入到Block中,或者通过JSContext的类方法+ (JSContext )currentContext;来获得。否则会造成循环引用使得内存无法被正确释放。*

比如上边自定义异常处理方法,就是赋给传入JSContext对象con,而不是其外创建的context对象,虽然它们其实是同一个对象。这是因为Block会对内部使用的在外部定义创建的对象做强引用,而JSContext也会对被赋予的Block做强引用,这样它们之间就形成了循环引用(Circular Reference)使得内存无法正常释放。
对于JSValue也不能直接从外部引用到Block中,因为每个JSValue上都有JSContext的引用 (@property(readonly, retain) JSContext *context;),JSContext再引用Block同样也会形成引用循环。

前面十分的简单方便而且高效,不过也仅限于数值型、布尔型、字符串、数组等这些基础类型。本文将扩展到更复杂的类型,介绍一下该强大的框架是如何让Objective-C对象和JavaScript对象进行直接互通的。

为了方便起见,以下所有代码中的JSContext对象都会添加如下的log方法和eventHandler:

JSContext *context = [[JSContext alloc] init];
context.exceptionHandler = ^(JSContext *con, JSValue *exception) {
    NSLog(@"%@", exception);
    con.exception = exception;
};

context[@"log"] = ^() {
NSArray *args = [JSContext currentArguments];
    for (id obj in args) {
        NSLog(@"%@", obj);
    }
};

6. 键值对编程—Dictionary

JSContext并不能让Objective-C和JavaScript的对象直接转换,毕竟两者的面向对象的设计方式是不同的:前者基于class,后者基于prototype。但所有的对象其实可以视为一组键值对的集合,所以JavaScript中的对象可以返回到Objective-C中当做NSDictionary类型进行访问。

JSContext *context = [[JSContext alloc] init];
JSValue *obj = [context evaluateScript:@"var jsObj = {number:7,name:'lile'};jsObj"];
NSDictionary *dic = [obj toDictionary];
NSLog(@"%@, %@", dic[@"name"], dic[@"number"]);

结果如下:
这里写图片描述

同样的,NSDicionary和NSMutableDictionary传入到JSContext之后也可以直接当对象来调用:

JSContext *context = [[JSContext alloc] init];
        NSDictionary *dic = @{@"name":@"lile", @"age":@(23)};
        context[@"dic"] = dic;
        [context evaluateScript:@"log(dic.name, dic['age'])"];

7. 语言穿梭机—JSExport协议

JavaScript可以脱离prototype继承完全用JSON来定义对象,但是Objective-C编程里可不能脱离类和继承写代码。所以JavaScriptCore就提供了JSExport作为两种语言的互通协议。JSExport中没有约定任何的方法,连可选的(@optional)都没有,但是所有继承了该协议(@protocol)的协议(注意不是Objective-C的类(@interface))中定义的方法,都可以在JSContext中被使用。语言表述起来有点绕,还是用例子来说明会更明确一点。

在.h文件中

#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>

@protocol PersonProtocol <JSExport>

@property (nonatomic, strong) NSDictionary *urls;

- (NSString *)fullName;

@end

@interface Person : NSObject <PersonProtocol>

@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;

@end

在.m文件中:

#import "Person.h"

@implementation Person

@synthesize firstName, lastName, urls;

- (NSString *)fullName {
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];;
}

@end

在上边的代码中,定义了一个PersonProtocol,并让它继承了神秘的JSExport协议,在新定义的协议中约定urls属性和fullName方法。之后又定义了Person类,除了让它实现PersonProtocol外,还定义了firstName和lastName属性。而fullName方法返回的则是两部分名字的结合。

下边就来创建一个Person对象,然后传入到JSContext中并尝试使用JavaScript来访问和修改该对象。

JSContext *context = [[JSContext alloc] init];

// initialize person object
Person *person = [[Person alloc] init];
context[@"p"] = person;
person.firstName = @"Li";
person.lastName = @"Le";
person.urls = @{@"site":@"http://blog.youkuaiyun.com/CoderLiLe"};

// ok to get fullName
[context evaluateScript:@"log(p.fullName());"];
// cannot access firstName
[context evaluateScript:@"log(p.firstName())"];
// ok to access dictionary as object
[context evaluateScript:@"log('site:', p.urls.site, 'blog:', p.urls.blog);"];
// ok to change urls property
[context evaluateScript:@"p.urls = {blog:'http://blog.youkuaiyun.com/CoderLiLe'}"];
[context evaluateScript:@"log('---AFTER CHANGE URLS ---')"];
[context evaluateScript:@"log('site:', p.urls.site, 'blog:', p.urls.blog);"];

// affect on Objective-C side as well  
NSLog(@"%@", person.urls);

结果如下:
这里写图片描述

References:
http://justsee.iteye.com/blog/2036713

基于simulink的预测电流控制策略的三相逆变器仿真 本文详细介绍了在Simulink中实现基于预测电流控制策略的三相逆变器仿真方法。主要内容包括:准备工作(安装必要软件及工具箱)、构建三相逆变器基础模型、设计预测电流控制器(包含状态空间建模和控制器设计)、实现控制逻辑、添加示波器观察输出、配置仿真参数以及运行仿真分析结果。通过MATLAB代码示例和Simulink模块说明,展示了如何选择最优开关状态来最小化电流误差。该仿真方法为研究快速响应、高精度的逆变器控制提供了实用工具,但需注意实际应用中可能需要的调试工作。 阅读详情

相关推荐

告别Overleaf!本地LaTeX环境配置:VSCode+TeXLive完全指南(Windows/Mac双平台)

本文详细介绍了如何在Windows和Mac平台上配置本地LaTeX环境,使用VSCode和TeXLive打造高效的专业写作工作流。从TeXLive安装到VSCode插件配置,再到高级技巧与性能优化,帮助用户摆脱Overleaf限制,实现更快速、更私密的学术写作体验。

3c4x5z6v7b的博客 952

关于iOS7里的JavaScriptCore framework

在iOS7沸沸扬扬的扁平化论战之外,WWDC 2013还是公布了很多让开发者小兴奋的点,其中包括多任务加强支持background fetch和transfer,近场通信的AirDrop和p2p,以及游戏控制器和游戏中心的加强;当然还包括了让web开发同学很兴奋JavaScriptCore了。下面henry/webryan来详细介绍下整合JavaScriptCore到原生应用的情况。1、什么是Ja

有志者事竟成-程序员也可以创造优雅的艺术 444

Ansys Lumerical FDTD硬件配置避坑指南:从RTX 4090到A100的GPU选择实战

本文针对Ansys Lumerical FDTD仿真计算,深入分析了从消费级RTX 4090到专业级A100的GPU硬件配置选择。文章指出,选择的关键在于显存容量能否容纳仿真模型,并对比了二者在显存、双精度算力及多卡扩展性上的核心差异,为不同预算和仿真规模的用户提供了实战避坑指南与配置建议。

weixin_29196891的博客 273

JavascriptCore framework in iOS7

JavaScriptCore 简介   iOS7 中新加入的 JavaScriptCore.framework 可能被大多数开发人员所忽略,但是如果你之前就在项目中用过自己编译JavaScriptCore来处理 JavaScript,那么你需要重新关注一下 JavaScriptCore.framework。   JavaScriptCore 是苹果 Safari 浏览器的 JavaScr...

shappy1978的专栏 129

【Unity】YooAsset + HybridCLR热更

本文介绍了Unity游戏开发中的热更新技术方案,重点对比了资源热更和代码热更的主流工具。资源热更方面分析了Asset Bundle、Addressable和YooAsset的优缺点;代码热更部分比较了xLua、ILRuntime、InjectFix和HybridCLR的性能特点。文章详细演示了HybridCLR+YooAsset的实践方案,包括加载热更新程序集、反射调用热更代码、资源打包部署等完整流程。该方案通过原生运行时实现程序集级热更,具有极低性能损耗和全生命周期适用性,配合YooAsset简化了资源管

欢迎指错||纠正||建议||水评+点赞&&评论&&关注&&转发 2919

工业机器人关节拆装流程_一文读懂模块化直驱电机及机器人关节模组

私信“干货”二字,即可领取138G伺服与机器人专属及电控资料!如果说芯片是智能行业最为重要的核心元件,那么电机几乎可以说是支撑了整个自动化和大工业生产以及现代社会最为重要的部件,全世界90%的能源是由电机发出来的,而70%是由电机消耗调的,电机可以说是整个人类社会能源循环的占有绝对地位的产品。普通伺服电机伺服电机其实已经算是电动机中比较高端的类型,特别是永磁同步类型的伺服电机,由于其启动快速,惯量...

weixin_32159771的博客 2155

Mac10.9和iOS7新公开的框架JavaScriptCore.framework

官网的介绍: The JavaScript Core framework (JavaScriptCore.framework) provides Objective-C wrapper classes for many standard JavaScript objects. Use this framework to evaluate JavaScript code and p

小蒙面侠的博客 6799

CTF全能工具箱ProV2:集成AI与94GB离线资源库,打造无网环境下的智能解题流水线

CTF全能工具箱ProV2是一款专为线下CTF比赛设计的All-in-One离线解决方案。它集成了94GB的庞大离线资源库,涵盖Web、逆向、Pwn等全方向工具链与知识库,并创新性地内置了本地AI大模型,可在断网环境下提供智能解题辅助,实现从信息收集到漏洞利用的智能流水线作业,极大提升比赛效率。

weixin_29240343的博客 424

JavaScriptCore.framework可能

转:http://justsee.iteye.com/blog/2036713 太长了 iOS7中新加入的JavaScriptCore.framework可能被大多数开发人员所忽略,但是如果你之前就在项目中用过自己编译JavaScriptCore来处理JavaScript,那么你需要重新关注一下JavaScriptCore.framework。 JavaScriptCore是苹果Saf

baidu_31071595的博客 368

RK3588 部署 YOLO26 目标检测:从训练到 NPU 推理

如果做垂直场景(工业缺陷、农作物、特定零件),需要自己标数据。采集图像(500+ 张,覆盖不同光照/角度)→ 筛选(删除模糊/无目标)→ LabelImg 标注(选择 YOLO 格式)→ 划分(train:val:test = 7:2:1)labelImg├── train/├── val/├── test/YOLO26 在 RK3588 上的全流程是 PC 端训练 + ONNX 导出 → RKNN 转换(INT8 量化)→ 板端推理。

m0_71589036的博客 110

AIPex:AI + 自然语言驱动的浏览器自动化扩展

AIPex是一款革命性的Chrome扩展,通过AI技术实现自然语言驱动的浏览器自动化。它支持30多种自动化工具,包括智能标签页管理(分组、切换、批量操作)、页面内容提取(文本、链接、元数据)、交互元素操作(点击、滚动)以及表单智能填写等功能。用户只需用自然语言下达指令,即可快速完成复杂的浏览器操作,大幅提升工作效率。AIPex特别适合需要处理大量重复性网页操作的用户,如数据分析师、产品经理等。

blues_C的博客 1132

ios7新增的Framework

新增的Framework 在iOS7中,新增了如下一些Framework:   1.Game Controller framework(GameController.framework):提供了与游戏相关的硬件通讯接口。 2.Sprite Kit framework(SpriteKit.framework):提供了基于精灵(sprite-based)的动画和图形渲染。 3.Mul...

hulefei29的专栏 100

SpringBoot + MyBatis-Plus 高效实现数据变更记录:从注解到通用审计方案(附源码)

*** 数据变更审计插件* 拦截增删改操作,自动记录变更日志*/@Component@Resource/*** 拦截SQL执行*/@Override/*** 数据变更审计插件* 拦截增删改操作,自动记录变更日志/*** 拦截SQL执行。

2601_94871597的博客 560

iOS中OC JavaScriptCore.framework框架的webView交互

iOS7之后苹果公司引入了JavaScriptCore.framework提供了更好的,快捷的,简单的js交互框架。但是iOS8之后苹果公司提供了WKWebView 以更好的交互,但是这个不支持JavaScriptCore.framework框架的,以下是我学习的一点感悟与心得,如若写的不到位或者有不对的地方欢迎大家指出!现在咱们切入主题: JavaScriptCore中类及协

公子纠的博客 2373

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

iOS开发:JavaScriptCore.framework的简单使用--JS与OC的交互篇

原文地址:http://www.cnblogs.com/shaoting/p/5247208.html iOS7之后苹果为众猿推出了JavaScriptCore.framework这个框架,这个框架为大家在与JS交互上提供了很大帮助,可以在html界面上调用OC方法并传参,也可以在OC上调用JS方法并传参.这里简单的介绍一下这个框架的使用.   javaScriptCore是一种

Bob的专栏 919

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

iOS7新特征汇总[03]新特征介绍3

提醒:这里是新特征汇总博文链接:iOS7新特征汇总 小引 上一篇文章(iOS7新特征汇总[02]新特征介绍2)中,笔者介绍了在iOS7中关于游戏、地图和AirDrop相关内容。本文将继续介绍iOS7中的新特征:程序间的音频(inter-App Audio)、点对点的连接、新增的Framework。 程序间的音频(inter-App Audio) Audio

有梦想的蜗牛 1739

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: Java中使用javadoc命令生成文档
下一篇: 一、android入门基础
CoderLiLe
博客等级 码龄11年 2粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值