>  기사  >  웹 프론트엔드  >  JS와 OC 간의 상호 변조 예에 대한 자세한 설명

JS와 OC 간의 상호 변조 예에 대한 자세한 설명

零下一度
零下一度원래의
2017-05-10 11:06:101610검색

1. JavaScript일반적으로 사용되는 핵심 클래스

JavaScriptCore 기능: JavaScriptCore는 Apple의 기본 API로 JS 및 OC 인터랙티브.

JSContext: JS 실행 환경, JS 코드를 실행하는 데 사용하고 JS에서 데이터를 얻는 데 사용

JSValue: JS에서 얻은 데이터 유형을 받는 데 사용되며 모든 객체일 수 있음 , 방법.

2. OC가 JS를 호출합니다

본질: JS 코드에 정의된 변수와 메서드를 OC를 통해 가져오고

을 호출합니다. 단계:

1. JS 실행 환경 생성

2. JS 코드 실행

3. JS 데이터(변수, 메소드) 가져오기

4. JS 데이터, 메소드 사용

2.1 JS에 정의된 변수 가져오기

OC를 통해 JS에 있는 변수의 값을 직접 수정할 수 있습니다

#pragma mark - 获取JS中定义的变量
- (void)getJSVar{
// JS代码
NSString *jsCode = @"var arr = [1,2,3]";
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// 执行JS代码
[ctx evaluateScript:jsCode];
// 因为变量直接定义在JS中,所以可以直接通过JSContext获取,根据变量名称获取,相当于字典的Key
// 只有先执行JS代码,才能获取变量
JSValue *jsArr = ctx[@"arr"]; 
  jsArr[0] = @5;
// 打印结果:5,2,3
NSLog(@"%@",jsArr);}

2.2 JS에 정의된 메소드를 가져오고 호출

JS 메소드를 호출하는 OC 구현

#pragma mark - OC调用JS
// OC调用JS方法,并获取返回结果
- (void)ocCallJSFunc{
NSString *jsCode =@"function hello(say){"
" return say; "
"}";
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// 因为方法直接定义在JS中,所以可以直接通过JSContext获取,根据方法名称获取,相当于字典的Key
// 执行JS代码
[ctx evaluateScript:jsCode];
// 获取JS方法,只有先执行JS代码,才能获取
JSValue *hello = ctx[@"hello"];
// OC调用JS方法,获取方法返回值
JSValue *result = [hello callWithArguments:@[@"你好"]];
// 打印结果:你好
NSLog(@"%@",result);
}

3. JS는 OC에서 블록을 호출합니다

본질: JS에는 처음에 OC 블록이 없습니다. 따라서 OC 블록을 직접 호출할 수는 없습니다. JS에서 OC 블록 메서드를 생성한 후 JS를 통해 호출해야 합니다.

단계:

1. JS 실행 환경 생성

2. JS에서 해당 OC 코드 생성

3. 환경에서 생성된 block 메소드를 OC의 블록에 호출할 수 있습니다.

3.1 JS가 OC에서 매개변수 없이 블록을 호출합니다

JS를 통해 OC에서 매개변수 없이 블록을 호출하고 싶습니다

#pragma mark - JS调用OC中不带参数的block
- (void)jsCallOCBlock1WithNoneArguments{
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// JS调用Block方式// 由于JS本身没有OC这个代码,需要给JS中赋值,就会自动生成右边的代码.
// 相当于在JS中定义一个叫eat的方法,eat的实现就是block中的实现,只要调用eat,就会调用block
ctx[@"eat"] = ^(){NSLog(@"吃东西"); 
  };
// JS执行代码,就会直接调用到block中
NSString*jsCode =@"eat()"; 
  [ctx evaluateScript:jsCode];}

3.2 JS가 OC에서 매개변수가 있는 블록을 호출합니다

JS를 통해 OC에서 매개변수가 있는 블록을 호출하고 싶습니다

- (void)jsCallOCBlockWithArguments{
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// 2.调用带有参数的block
// 还是一样的写法,会在JS中生成eat方法,只不过通过[JSContext currentArguments]获取JS执行方法时的参数
ctx[@"eat"] = ^(){
// 获取JS调用参数
NSArray *arguments = [JSContext currentArguments];
NSLog(@"吃%@",arguments[0]); 
  };
// JS执行代码,调用eat方法,并传入参数面包
NSString*jsCode =@"eat('面包')"; 
  [ctx evaluateScript:jsCode];
}

4. JS는 OC에서 클래스를 호출합니다

본질: JS에는 처음에는 OC 클래스가 없습니다. 먼저 JS에서 OC 클래스를 생성한 다음 JS를 통해 호출해야 합니다.

단계

1. OC 클래스는 JSExport 프로토콜을 준수하는 한 JS는 이 클래스를 생성합니다

2. 충분하지 않습니다. 속성과 메서드가 있으며 JS에서도 생성해야 합니다

3.JSExport 자체에는 자체 속성과 메서드가 없으므로 프로토콜,

상속JSExport를 자체 프로토콜에서 JS

4에서 사용해야 하는 속성과 메서드를 노출합니다. 이러한 방식으로 클래스는 자체 프로토콜만 상속하면 됩니다. JS는 자체 프로토콜에 선언된 속성 및 메소드를 포함하여 클래스를 자동으로 생성합니다

4.1 JS가 OC 사용자 정의 클래스 호출

사용자 정의 프로토콜(PersonJSExport)

@protocolPersonJSExport
@property(nonatomic, strong) NSString *name;
-(void)play;
// 调用多个参数的方法,JS函数命名规则和OC还不一样,很可能调用不到对应的JS生成的函数,为了保证生成的JS函数和OC方法名一致,OC提供了一个宏JSExportAs,用来告诉JS应该生成什么样的函数对应OC的方法,这样就不会调错了。
// PropertyName:JS函数生成的名字
// Selector:OC方法名
// JS就会自动生成playGame这个方法JSExportAs(playGame,
- (void)playWithGame:(NSString *)gametime:(NSString *)time);
@end
사용자 정의 클래스(Person)

@interfacePerson: NSObject
@property(nonatomic, strong) NSString *name;
-(void)playWithGame:(NSString*)gametime:(NSString*)time;
@end
@implementationPerson
-(void)play{
NSLog(@"%@玩",_name);
}
-(void)playWithGame:(NSString*)gametime:(NSString*)time{
NSLog(@"%@在%@玩%@",_name,time,game);
}
@end
JS를 통해 OC 사용자 정의 클래스 호출

#pragmamark - JS调用OC自定义类
- (void)jsCallOCCustomClass{
// 创建Person对象
Person *p = [[Person alloc] init];   
p.name = @"zs";   
JSContext *ctx = [[JSContext alloc] init];
// 会在JS中生成Person对象,并且拥有所有值
// 前提:Person对象必须遵守JSExport协议,
ctx[@"person"] = p;
// 执行JS代码
// 注意:这里的person一定要跟上面声明的一样,因为生成的对象是用person引用// NSString *jsCode = @"person.play()";
NSString *jsCode = @"person.playGame('德州扑克','晚上')"; 
  [ctx evaluateScript:jsCode];
}
4.1 JS OC 시스템 클래스 호출

문제: JS를 통해 시스템 자체 클래스를 호출하고 싶습니다. 시스템 자체 클래스의 파일을 수정할 수 없습니다.

사용자 정의 클래스를 호출하는 것과 마찬가지로 사용자 정의 클래스도 만들어야 합니다. JSExport를 상속하고 어떤 속성을 노출해야 하는지 설명하는 프로토콜(우리가 원하는 시스템 클래스 속성은 자체 프로토콜 선언에 노출됨)

런타임을 통해 클래스에 프로토콜 추가

사용자 정의 프로토콜 (UILabelJSExport)

@protocolUILabelJSExport
@property(nonatomic, strong) NSString *text;
@end
JS 호출 OC 시스템 클래스

#pragma mark - JS调用OC系统类
- (void)jsCallOCSystemClass{ 
  // 给系统类添加协议 class_addProtocol([UILabel class],
@protocol(UILabelJSExport)); 
  // 创建UILabel 
UILabel *label= [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
[self.view addSubview:label];
JSContext *ctx = [[JSContext alloc] init];   
// 就会在JS中生成label对象,并且用laebl引用
ctx[@"label"] =label;
// 利用JS给label设置文本内容
NSString *jsCode = @"label.text = 'Oh Year'"; 
  [ctx evaluateScript:jsCode];
}
[관련 추천]

1.

무료 js 온라인 동영상 튜토리얼

2.

JavaScript 중국어 참조 매뉴얼

3. php.cn Dugu Jiujian (3) - JavaScript 동영상 튜토리얼

위 내용은 JS와 OC 간의 상호 변조 예에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.