最近学习了下hotfix的时候oc转js的写法, 记录下...

1.require

UIView *view = [[UIView alloc] init];
// -> js

require('UIView')
var view = UIView.alloc().init();
//或者
var view = require('UIView').alloc().init();

2.setter or getter

view.backgroundColor = [UIColor redColor];
// -> js

view.setBackgroundColor(UIColor.redColor());
var color = view.backgroundColor();

3.方法调用时方法名转换及参数

[super sortByIndex:index sortState:sortState];
// -> js
super.sortByIndex_sortState(index, sortState);


NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];

var indexPath = require('NSIndexPath').indexPathForRow_inSection(0, 1);

4.最常用的方法: 方法覆盖

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:    (NSIndexPath *)indexPath{}

defineClass("JPTableViewController", {
  tableView_didSelectRowAtIndexPath: function(tableView, indexPath) {
    ...
  },
})

若是方法中有下划线, 就使用双下划线

5.在方法名前加 ORIG 即可调用未覆盖前的 OC 原方法, 覆盖分类方法一致

- (void)viewDidLoad {}

defineClass("MarketsRevisionViewController", {
    viewDidLoad: function(){
        //给属性赋初始值, 然后覆盖viewDidLoad
        self.setMbook("");
        self.ORIGviewDidLoad();
    }
});

6.获取并修改oc的property

@interface UIViewController
@property (nonatomic) NSArray *data;
@end

defineClass("UIViewController", {
    viewDidLoad:function() {
        var data = self.data();
        //把data数组转化为js的data, 然后加入新元素
        self.setData(data.toJS().push("jason"));
    },
})

7.获取并改变私有成员变量

@implementation UIViewController {
    NSArray *_data;
}
@end

defineClass("UIViewController", {
    viewDidLoad: function(){
        //采取valurForKey的方式
        var data = self.valueForKey("_data");
        self.setValue_forKey(["JSPatch"], "_data")
    },
})

8.protocol js中实现oc协议的写法

defineClass("ViewController: UIViewController <UIAlertViewDelegate>", {
    viewDidAppear:function(){
    var alertView = require('UIAlertView').alloc().initWithTitle_message_delegate_cancleButtonTitle_otherButtonTitles(
            "Alert", self.dataSource().objectAtIndex(indexPath.row()), self, "ok", null
        )
    alertView.show();
}
    alertView_clickButtonAtIndex:function(alertView, buttonIndex){
    console.log("clickIndex" + buttonIndex)
}

})

9.Struct 结构体 JSPatch原生支持四种类型 CGRect CGPoint CGSize NSRange

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.center = CGPointMake(50, 50);
[view sizeThatFits:CGSizeMake:(30, 30)];

CGFloat x = view.frame.origin.x;

NSRange range = NSMakeRange(0, 2);

//-> js

var view = UIView.alloc().initWithFrame({0, 0 , 100, 100});
view.setCenter({x:50, y:50});
view.sizeThatFits({width:100, height:100});

var x = view.frame().x;
var range = {location:0, length:2};

10.Selector 选择器

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventsTouchUpInside];

// -> js

var button = UIButton.buttonWithType(0);
button.addTarget_action_forControlEvents(self, "buttonClick:", 1<<6);

11.nil OC中的nil在js中用null或者undefined代替, OC中的null在js中用nsnull代替

@implementation
+ (BOOL)testNull:(NSNull *)null {
return [null isKindof:[NSNull class]];
}
@end

//-> js

require('UIViewController').testNull(nsnull); return YES(true), 1
require('UIViewController').testNull(null); return NO(false), 0;

->>>在JS里面判断为空要判断false

var url = 'www.baidu.com';
var data = NSData.dataWithContentsOfURL(NSURL.urlWithString(url));

if (data != null) {}; //注: js中不能这样判断空
正确如下:
if (!data){}; 

12.NSArray / NSString / NSDictionary

@implementation
+ (NSArray *)arr {
    return [@[@"a", @"b"] mutableCopy];
}
@end

// -> js
//不转为对应的js类型
require ("UIViewController")
var string = UIViewController.data().objectAtIndex(1);
string.appendString("hotfix")
console.log(string)

//转为对应的js类型

var data = require('UIViewController').data.toJS();
data.push("hotfix");

13.Block 在js中block的写法, 先使用 block(paramTypes, function) 接口包装

@implementation 
+ (void)request:(void(^)(NSString *content, BOOL success))callback{
    callback(@"I'm content", YES);
}
@end

//-> js

require("UIViewController").request(block("NSString *, BOOL",     function(content, success){
    if (success) log(content);
}))

在block中无法直接调用self, 需要用临时变量保存
defineClass("UIViewController", {
    viewDidLoad:function(){
        var weSelf = self;
        require("UIView").callback(block(function(){
            weSelf.doSomething();
        }));
    }
})

14.weak / strong js中声明一个weak属性的做法为 __weak(), 在oc中为了避免循环引用, 经常会weak属性;

- (void)test {
    __weak id weakSelf = self;
    [self setBlock:^(){
        [weakSelf haha];
    }]
}
// -> js

var weakSelf = __weak(self);
self.setBlock(block(function(){
    weakSelf.haha();
}))

在在使用 weakSelf 的时候在block内部变为strong属性, 写法一致

var weakSelf = __weak(self);
self.setBlock(block(function(){
    var strongSelf = __strong(weakSelf);
    strongSelf.haha();
}))

15.GCD js在线程的调用中比较简单

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  // do something
});
dispatch_async(dispatch_get_main_queue(), ^{
  // do something
});

// -> js

dispatch_after(1.0, function(){
    .....
})
dispatch_async(function(){
    ......
})

16.常量、枚举、全局变量 在 js 中的使用

OC中的常量/枚举不能直接在JS中调用, 可以用具体值代替

[btn addTarget:self action:@selector(handleBtn) forControlEvents:UIControlEventTouchUpInside];
//-> js
btn.addTarget_action_forControlEvents(self, "handleBtn", 1 << 6);
//重新定义也可以
var UIControlEventTouchUpInside  = 1 << 6;
btn.addTarget_action_forControlEvents(self, "handleBtn", UIControlEventTouchUpInside);

像 NSForegroundColorAttributeName 这样的静态字符串变量, 可以打印出来值

static 全局变量无法在 JS 上获取到,需要携程类方法或实例方法返回
static NSString *name;
@implementation UIViewController
+ (NSString *)name {
      return name;
}
@end

var name = UIViewController.name();

基本可以解决日常需要

results matching ""

    No results matching ""