免责声明:这是一篇很长的文章,但对于那些努力使用新的 ObjectiveC JavascriptCore 框架并在 ObjC 和 JS 之间进行异步编码的人来说可能非常有价值。
您好,我对 Objective C 非常陌生,正在将 javascript 通信库集成到我的 iOS 应用程序中。
不管怎样,我一直在尝试使用 iOS7 中引入的新 ObjectiveC JavaScriptCore 框架。尽管到目前为止记录还很少,但它的大部分内容都非常棒。
混合语言约定确实很奇怪,但在某些方面也是一种解放。
我应该补充一点,我当然使用 ARC,所以这对 Javascript 世界有很大帮助。但我有一个非常具体的问题,涉及在 ObjectiveC 和 JSContext 回调之间移动时的内存使用问题。就像我在 Javascript 中执行一个函数,然后执行一些异步代码,然后回调到定义的 ObjectiveC 块,然后调用定义的 JS 回调......我只是想确保我做得正确(即.不会在某些地方泄漏内存)!
只是为了正确地做事(因为我引用了一个类self
为了调用 ObjectiveC 回调,我创建了一个weakSelf
所以它与 ARC 配合得很好(引用自问题:在这个块中强烈捕获 self 可能会导致保留周期 https://stackoverflow.com/questions/14556605/capturing-self-strongly-in-this-block-is-likely-to-lead-to-a-retain-cycle):
__unsafe_unretained typeof(self) weakSelf = self;
现在,假设我有一个JSContext
并向其添加一个函数。我希望这个函数采用回调函数并使用“Hello”作为参数来调用它以及传递另一个函数作为回调. ie.
// Add a new JSContext.
JSContext context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Add a function to the context. This function takes a callBack function and calls it back with "Hello"
[context evaluateScript: @"var functionA = function(callBack){
var aMessage = "Foo";
callBack(aMessage, function(message){
/* message should say: Foo Bar */
});
}" ];
// Note, if you try to copy this code, you will have to get rid of the returns in the JS script.
好的,我们已经了解了基本的 JS 方面的内容。现在添加 ObjectiveS 复杂性。我将添加第一个 Objective C CallBack 块:
context[@"functionB"] = ^(NSString *theMessage, JSValue *theCallBack){
[weakSelf objCFunction:theMessage withCallBack:theCallBack];
};
在同一个类中,所有这一切都发生在我也有方法定义中。这是我最关心的地方:
-(void)objCFunction:(NSString *)message withCallBack:(JSValue *)callBack
{
NSString *concatenatedString = [NSString stringWithFormat:@"%@%@", message, @"Bar"];
[callBack callWithArguments:@[concatenatedString]];
}
所以当我打电话时:
[context evaluateScript: @"functionA(functionB);" ];
它应该穿过链条,并且它的作用正是我所期望的。
我主要担心的是,我希望我不会以某种方式捕获这条链上某个地方的 JSValue,然后该 JSValue 会泄漏出去。
任何帮助我理解 ARC/JSMachine 如何管理这种在 Objective C 和 Javascript 之间流畅调用回调的方法的帮助都将非常有价值!
另外,我希望这个问题可以帮助其他正在尝试这个框架的人。
Thanks!