gpt4 book ai didi

objective-c - ObjectiveC 和 JavaScriptCore : Will using this method of calling CallBacks cause memory issues?

转载 作者:太空狗 更新时间:2023-10-30 03:44:30 25 4
gpt4 key购买 nike

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

大家好,我是 Objective C 的新手,我正在将一个 javascript 通信库集成到我的 iOS 应用中。

无论如何,我一直在尝试使用 iOS7 中引入的新 ObjectiveC JavaScriptCore 框架。它在大多数情况下都非常棒,尽管到目前为止的文档还很少。

混合语言约定确实很奇怪,但在某些方面也有点解放。

我应该补充一点,我当然在使用 ARC,所以这对 Javascript 世界有很大帮助。但我有一个非常具体的问题,即在 ObjectiveC 和 JSContext 回调之间移动时的内存使用问题。就像我在 Javascript 中执行一个函数,然后执行一些异步代码,然后回调到定义的 ObjectiveC block ,然后调用定义的 JS 回调......我只是想确保我做对了(即. 没有在某些地方泄漏内存)!

只是为了正确地做事(因为我引用了一个类 self 来调用 ObjectiveC 回调我创建了一个 weakSelf 所以它与 ARC 一起玩得很好(引用自问题: capturing self strongly in this block is likely to lead to a retain cycle ):

__unsafe_unretained typeof(self) weakSelf = self;

现在,假设我有一个 JSContext 并向它添加一个函数。我希望此函数采用回调函数并使用“Hello”作为参数调用它并将另一个函数作为回调传递。即。

// 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 block :

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 然后泄漏出去。

如果能帮助我理解 ARC/JSMachine 如何管理这种在 Objective C 和 Javascript 之间流畅地调用回调的方法,那将是非常有值(value)的!

另外,我希望这个问题能帮助其他正在试验这个框架的人。

谢谢!

最佳答案

当您有两个对象时,就会出现循环保留问题,每个对象都保留另一个对象的一部分。它不特定于 JavascriptCore。它甚至不特定于 block ,尽管 block 使问题更容易犯错。

例如

@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 现在位于通过分配 block 创建的上下文中的函数 obj 中到 @"aFunc"。同样,上下文会被保留,因为它自己强烈保留的值之一保留在 self.badProp 中。

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

@property (strong,nonatomic) NSString *goodProp;


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

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

您的代码不是问题,因为简单地通过方法传递 JSValue(甚至是函数)不会保留它。

另一种思考方式可能是:在 objCFunction:withCallBack: 执行之后,self 表示的对象是否仍然可以访问传递的 JSValue 回调?如果不是,则没有保留周期。

关于objective-c - ObjectiveC 和 JavaScriptCore : Will using this method of calling CallBacks cause memory issues?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21147613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com