ObjectiveC和JavaScriptCore

ObjectiveC和JavaScriptCore

本文介绍了ObjectiveC和JavaScriptCore:使用这种调用CallBacks的方法会导致内存问题吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

免责声明:这是一篇很长的帖子,但对于那些使用新的ObjectiveC JavascriptCore框架并在ObjC和JS之间进行异步编码的人来说,这可能非常有价值。

您好,我是Objective C的新手,并且正在将javascript通信库集成到我的iOS应用程序中。

Hi there, I'm super new to Objective C and am integrating a javascript communication library into my iOS app.

无论如何,我是我一直在尝试使用iOS7中引入的新ObjectiveC JavaScriptCore框架。到目前为止,它在很大程度上都是非常棒的。但

Anyway, I've been trying my hand at using the new ObjectiveC JavaScriptCore Framework introduced in iOS7. It's pretty awesome for the most part, though quite poorly documented so far.

混合语言惯例真的很奇怪,但在某些方面也有点解放。

It's really strange mixing language conventions, but also kind of liberating in some ways.

我应该补充说我当然正在使用ARC,所以这有助于从Javascript世界中获得很多。但是,当在ObjectiveC和JSContext callBack之间移动时,我有一个非常具体的内存使用问题。就像我在Javascript中执行一个函数,然后执行一些异步代码,然后回调到一个定义的ObjectiveC块,然后调用一个定义的JS回调...我只是想确保我做得对(即不要在一些地方泄露记忆)!

I should add that I am of course using ARC, so that helps a lot coming from the Javascript world. But I have a question that's pretty specific around memory use issues when moving between ObjectiveC and the JSContext callBacks. Like if I execute a function in Javascript that then does some asynchronous code, and then calls back to a defined ObjectiveC block, and then that calls a defined JS callback... I just want to make sure I'm doing it right (ie. not leaking memory some place)!

只是为了做正确的事情(因为我引用了一个类 self 来调用ObjectiveC callBacks我创建了一个 weakSelf 所以它与ARC结合得很好(引自问题:):( / p>

Just to do things proper (because I reference a the class self to call the ObjectiveC callBacks I create a weakSelf so it plays nice with ARC (referenced from question: capturing self strongly in this block is likely to lead to a retain cycle):

__unsafe_unretained typeof(self) weakSelf = self;

现在,假设我有一个 JSContext 并添加一个函数。我希望这个函数带一个callBack函数并调用它Hello作为参数以及将另一个函数作为调用传递回到即可。 ie。

Now, say I have a JSContext and add a function to it. I want this function to take a callBack function and call it with "Hello" as an argument as well as pass ANOTHER function as a callBack. 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方面的东西。现在添加ObjectiveC复杂性。我要添加第一个ObjectiveC CallBack块:

Okay, so we have our basic JS side of things. Now to add the ObjectiveC complexity. I'm going to add the first ObjectiveC CallBack block:

context[@"functionB"] = ^(NSString *theMessage, JSValue *theCallBack){
    [weakSelf objCFunction:theMessage withCallBack:theCallBack];
};

在同一个类中,所有这一切都发生在我也有方法定义。 这是引起我最关注的地方

In the same class all this is happening in I also have the method definition. This is the place that causes the most concern to me:

-(void)objCFunction:(NSString *)message withCallBack:(JSValue *)callBack
{
    NSString *concatenatedString = [NSString stringWithFormat:@"%@%@", message, @"Bar"];
    [callBack callWithArguments:@[concatenatedString]];
}

所以当我打电话时:

[context evaluateScript: @"functionA(functionB);" ];

它应该通过链,它完全符合我的预期。

It should pass through the chain, and it does exactly what I expect it to do.

我主要担心的是,我希望我不会以某种方式捕获沿着这条链泄漏的JSValue。

My main concern is that I hope I'm not somehow capturing a JSValue somewhere along this chain that is then leaking out.

帮助我理解ARC / JSMachine如何管理这种在Objective C和Javascript之间流畅调用callBacks的方法的任何帮助都是非常有价值的!

Any help in helping me understand how ARC/the JSMachine would manage this approach to calling callBacks fluidly between Objective C and Javascript, would be super valuable!

另外,我希望这个问题可以帮助那些正在尝试这个框架的人。

Also, I hope this question helps others out there who are experimenting with this framework.

谢谢!

推荐答案

当你有两个对象时,就会出现保留周期的问题,每个对象都保留另一个对象的一部分。它不是特定于JavascriptCore。它甚至不是特定于块,虽然块使问题更容易犯错。

The problem with retain cycles occurs when you have two objects, each of which retains part of another. It's not specific to JavascriptCore. It's not even specific to blocks although blocks make the problem much easier to blunder into.

例如。

@interface ObjcClass : NSObject
@property (strong,nonatomic) JSValue *badProp;


- (void) makeEvilRetainWithContext:(JSContext *) context;
@end

- (void) makeEvilRetainWithContext:(JSContext *) context{
  context[@"aFunc"]=^(JSValue *jsValue){
    self.badProp=jsValue;
  };
}

self.context [@aFunc] 现在保留ObjcClass对象,因为 self.badProp 现在位于通过将块分配给创建的上下文中的函数obj内@ aFunc。同样,上下文被保留,因为其自身的一个强保留值保留在 self.badProp 中。

The self.context[@"aFunc"] now retains the ObjcClass object because self.badProp is now inside the function obj inside the context created by assigning the block to @"aFunc". Likewise, the context is retained because one of its own strongly retained values is retained in self.badProp.

真的,避免这一切的最好方法就是不要尝试将JSValue存储在objective-c对象中。似乎没有必要这样做,例如

Really, the best way to avoid all this is just to not try and store JSValue in objective-c objects ever. There really doesn't seem to be a need to do so e.g.

@property (strong,nonatomic) NSString *goodProp;


- (void) makeGoodFunc:(JSContext *) context;
@end

- (void) makeGoodFunc:(JSContext *) context{
  context[@"aFunc"]=^(JSValue *jsValue){
    self.goodProp=[JSValue toString];
  };
}

您的代码不是问题,因为只需传递一个JSValue(甚至一个函数) )通过一种方法不会保留它。

You code isn't a problem because simply passing a JSValue (even a function) through a method won't retain it.

另一种想到它的方法可能是:之后, objCFunction:withCallBack:执行,无论如何都会由 self 表示的对象,以访问以 callBack 传递的JSValue?如果没有,则没有保留周期。

Another way to think of it might be: After, objCFunction:withCallBack: executes, would there be anyway for the object represented by self to access the JSValue passed as callBack? If not, then no retain cycle.

这篇关于ObjectiveC和JavaScriptCore:使用这种调用CallBacks的方法会导致内存问题吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:26