mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-24 20:00:37 +00:00
docs: 批量博文
This commit is contained in:
155
Chapter1 - iOS/1.29.md
Normal file
155
Chapter1 - iOS/1.29.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# JavascriptCore
|
||||
|
||||
|
||||
|
||||
1、JSCore 是基于 webkit 以 C/C++ 实现的一个 js 包装,让 js 和 Native 交互变得更加简单。
|
||||
|
||||
- JScontext
|
||||
JSContext 代表一个 JavaScript 的执行环境的一个实例。所有JavaScript执行都是在上下文内进行。JSContext还用于管理对象的生命周期内 JavaScript 的虚拟机
|
||||
- JSValue
|
||||
JSValue 是用来接收 JSContext 执行后的返回结果。JSValue 可以是 JS 的任意类型(变量、对象、函数...)
|
||||
- JSManagedValue
|
||||
JSManagedValue 是对 JSValue 的封装,可以解决 JS 和 OC 之间循环引用的问题。JSManagedValue 最常用的用法就是安全的从内存堆区里面引用 JSValue 对象.如果 JSValue 存储在内存的堆区的方式是不正确的,很容易造成循环引用,然后导致 JSContext 对象不能正确的释放掉.
|
||||
- JSExport
|
||||
是一个协议,用来将 Native 对象暴露给 JS,这个对象可以指向给自身和别的对象。
|
||||
- JSVirtualMachine
|
||||
管理 JS 对象空间和所需的资源
|
||||
|
||||
2、Native 调用 JS
|
||||
|
||||
- 加载 JS 代码
|
||||
(JSValue *)evaluateScript:(NSString *)script;
|
||||
|
||||
- 调用 JS 方法
|
||||
JSvalue *callBack = self.context[@"sayHi"];
|
||||
[callback callWithArguments:@[@"杭城小刘"]];
|
||||
|
||||
|
||||
3、JS 调用 Native
|
||||
|
||||
- 通过 Block 实现。然后在 JS 中直接调用方法即可。需要注意的是在 Block 内部不要直接使用外部定义的 JScontext 对象或 JSValue ,应该作为参数传递进来,或者通过 + (JSContext *)currentContext; 来获取。否则会造成循环引用、内存无法被正确回收
|
||||
self.context[@"showMessage"] = ^(NSString *message){
|
||||
UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
|
||||
[alertCtr addAction:cancel];
|
||||
//注意:方法是在子线程中执行的,需要跟新UI的话,需要切入主线程。
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSealf presentViewController:alertCtr animated:YES completion:nil];
|
||||
});
|
||||
};
|
||||
- 通过 JSExport 协议实现; JS 需要通过 OC 中注入的对象来调方法,那么方法需要在协议中声明,并且在注入的对象中实现;在 webview 加载完成的时候注入实现协议的 Native 对象
|
||||
//声明协议
|
||||
|
||||
@proptocol JSInject<JSExport>
|
||||
- (void)showMessage:(NSString *)message;
|
||||
@end
|
||||
|
||||
//实现相应的协议
|
||||
|
||||
- (void)showMessage:(NSString *)message{
|
||||
UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
|
||||
[alertCtr addAction:cancel];
|
||||
//注意:方法是在子线程中执行的,需要跟新UI的话,需要切入主线程。
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSealf presentViewController:alertCtr animated:YES completion:nil];
|
||||
});
|
||||
}
|
||||
|
||||
//注入
|
||||
|
||||
- (void)webViewDidFinishLoad:(UIWebView *)webView
|
||||
{
|
||||
//从webview上获取相应的JSContext。
|
||||
self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
|
||||
|
||||
//注入JS需要的“OC”对象
|
||||
self.context[@"Bridge"] = [JSInject new];
|
||||
}
|
||||
|
||||
|
||||
举个🌰
|
||||
|
||||
JS call Native
|
||||
|
||||
//对外要暴露的 native 对象(其中挂载了一些属性和方法)
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <JavaScriptCore/JavaScriptCore.h>
|
||||
|
||||
@protocol PersonInjectExport<JSExport>
|
||||
|
||||
@property (nonatomic, strong) NSString *name;
|
||||
|
||||
@property (nonatomic, strong) NSString *hobby;
|
||||
|
||||
- (id)sayHi;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface PersonInject : NSObject<PersonInjectExport>
|
||||
|
||||
@property (nonatomic, strong) NSString *name;
|
||||
|
||||
@property (nonatomic, strong) NSString *hobby;
|
||||
|
||||
- (id)sayHi;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// viewcontroller
|
||||
|
||||
- (void)webViewDidFinishLoad:(UIWebView *)webView{
|
||||
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
|
||||
PersonInject *person = [[PersonInject alloc] init];
|
||||
person.name = @"杭城小刘";
|
||||
person.hobby = @"Coding、Movie、Music、Table tennis、Fit";
|
||||
self.jsContext[@"lbp"] = person;
|
||||
}
|
||||
|
||||
//JS
|
||||
<body>
|
||||
|
||||
嗨。大家好我是
|
||||
<p id="name">***</p>
|
||||
|
||||
<button id="show">那你做个自我介绍吧</button>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
var u = navigator.userAgent
|
||||
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1
|
||||
var isiOS = u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) //ios终端
|
||||
|
||||
document.getElementById("show").onclick = function () {
|
||||
if (isiOS) {
|
||||
document.getElementById("name").innerHTML = lbp.name;
|
||||
setTimeout(() => {
|
||||
alert(lbp.sayHi());
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
Native call JS
|
||||
|
||||
//Native
|
||||
- (void)callJS{
|
||||
JSValue *functionName = self.jsContext[@"sum"];
|
||||
NSInteger sum = [[functionName callWithArguments:@[@"2",@"18"]] toInt32];;
|
||||
|
||||
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"来自JS 的计算" message:[NSString stringWithFormat:@"%zd",sum] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
|
||||
[alertVC addAction:okAction];
|
||||
[self presentViewController:alertVC animated:YES completion:nil];
|
||||
}
|
||||
|
||||
//JS
|
||||
function sum(a ,b){
|
||||
return parseInt(a) + parseInt(b);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user