Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于block的使用问题 (JPBlock Extension) #830

Open
ziiip opened this issue Jun 27, 2018 · 0 comments
Open

关于block的使用问题 (JPBlock Extension) #830

ziiip opened this issue Jun 27, 2018 · 0 comments

Comments

@ziiip
Copy link

ziiip commented Jun 27, 2018

概述

最近在研究JSPatch,在尝试 Extension 'JPBlock' 的时候,发现一些问题。而且这些问题的出现是有一定几率的。

重现

使用最新的 Master 上的代码,打开 JSPatchDemo.xcodeproj
修改 JPViewController 的代码如下

#import "JPViewController.h"
typedef BOOL(^SimpleBlock)(NSString *);

@interface JPViewController ()
@property (nonatomic, copy) SimpleBlock simpleBlock;
@end

@implementation JPViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 104, [UIScreen mainScreen].bounds.size.width, 50)];
    [btn setTitle:@"Prepare Environment" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(handleFirsetBtn:) forControlEvents:UIControlEventTouchUpInside];
    [btn setBackgroundColor:[UIColor grayColor]];
    [self.view addSubview:btn];
    
    
    btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 158, [UIScreen mainScreen].bounds.size.width, 50)];
    [btn setTitle:@"Exec simpleBlock in JS" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(handleSecondBtn:) forControlEvents:UIControlEventTouchUpInside];
    [btn setBackgroundColor:[UIColor grayColor]];
    [self.view addSubview:btn];
    
    
    btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 212, [UIScreen mainScreen].bounds.size.width, 50)];
    [btn setTitle:@"Exec simpleBlock directly" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(handleThirdBtn:) forControlEvents:UIControlEventTouchUpInside];
    [btn setBackgroundColor:[UIColor grayColor]];
    [self.view addSubview:btn];
}

- (void)handleFirsetBtn:(id)sender
{
    //
    [self prepareEnv];
}

- (void)handleSecondBtn:(id)sender
{
    
}

- (void)handleThirdBtn:(id)sender
{
    if (_simpleBlock) {
        _simpleBlock(@"Calling in OC Directly");
    }
}


- (void)prepareEnv {
//    [self setSimpleBlock:nil];
    _simpleBlock = nil;
}

- (void)configureCurrentSimpleBlock:(SimpleBlock)block {
    _simpleBlock = block;
}

- (SimpleBlock)currentSimpleBlock {
    return _simpleBlock;
}
@end

同时修改demo.js

require('JPEngine').addExtensions(['JPBlock']);
defineClass('JPViewController', {
  viewDidLoad: function() {
    self.ORIGviewDidLoad()
    self.prepareEnv();
  },
  prepareEnv: function() {
    self.ORIGprepareEnv();

    // Define block with JS
    var tempBlock = block('BOOL, NSString *', function(message) {
      console.log("Block from JS and set in 'prepareEnv' get called with message " + message.toJS())
    })

    self.setSimpleBlock(tempBlock)

    // Case 1: 
    // self.currentSimpleBlock()("Calling in prepareEnv")

    // Case 2:
    var simpleBlockFromOC = self.simpleBlock(); simpleBlockFromOC("Calling in prepareEnv");
  },

  handleSecondBtn: function(sender) {
    var theBlock = self.simpleBlock();
    theBlock("Calling from JS");
  },
})

然后运行,app 有可能一启动就出现崩溃,如果没有崩溃,点击多几次 “Prepare Environment” 按钮,也可能出现同样的崩溃。

2018-06-27 18:18:31.698 JSPatchDemo[1757:317836] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSMethodSignature signatureWithObjCTypes:]: type signature is empty.'
*** First throw call stack:
(0x181f2adb0 0x18158ff80 0x181e274fc 0x185a468b4 0x1859ed604 0x1859ede54 0x185987774 0x1859e3f10 0x1859e046c 0x185a47e40 0x185a45f70 0x185a45af8 0x185a46cf0 0x1855ee518 0x185a2d9f8 0x185a2d9a0 0x185a2da04 0x185a2dbd4 0x185a27b98 0x1859536bc 0x1855f226c 0x1855f201c 0x1859e231c 0x1000731f0 0x181f2ea1c 0x181e2cc5c 0x100096454 0x1870c0be8 0x1870c0b64 0x1870a8870 0x1870c0454 0x1870c0084 0x1870b8c20 0x18708904c 0x187087628 0x181ee109c 0x181ee0b30 0x181ede830 0x181e08c50 0x1836f0088 0x1870f2088 0x10009fec8 0x1819a68b8)
libc++abi.dylib: terminating with uncaught exception of type NSException

与此同时,如果成功启动,点击按钮 Exec simpleBlock in JS 有时候还可以出现 Exception:

Printing description of log:
js exception, 
msg: simpleBlockFromOC is not a function. (In 'simpleBlockFromOC("Calling in prepareEnv")', 'simpleBlockFromOC' is an instance of Object), 
stack: 
 prepareEnv@main.js:22:73
JSPatch.js:169:27
[native code]
viewDidLoad@main.js:6:27
JSPatch.js:153:41

关于机型和系统

在 iPhone6 Plus iOS 9.9.3 上, 重现几率极大
在 iPhoneX iOS 11.3.1 上,重现几率比较小,一般能正常启动,但不断点击按钮 Exec simpleBlock in JS ,大概20次内,也能重现。

疑问

@bang590 这个是不是说明,JPBlock还不完全支持“block 从JS传到OC,在传回JS,并执行”的情况?还是哪里的代码写得有问题?
问题的出现是随机的,这种随机性,感觉跟资源释放有关,或者跟内存地址被污染有关?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant