ObjectiveC 和 JavaScriptCore:使用这种调用回调的方法会导致内存问题吗?

2024-05-23

免责声明:这是一篇很长的文章,但对于那些努力使用新的 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!


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

E.g.

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


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

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

The self.context[@"aFunc"]现在保留 ObjcClass 对象,因为self.badProp现在位于通过将块分配给创建的上下文中的函数 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访问传递的 JSValuecallBack?如果没有,则没有保留周期。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ObjectiveC 和 JavaScriptCore:使用这种调用回调的方法会导致内存问题吗? 的相关文章

  • Android - 保留或删除应用程序卸载时创建的文件

    我创建了一个应用程序 用于创建文件并将其存储到 SD 卡 有没有办法将文件夹与应用程序绑定 以便当用户在 Android 设备上运行卸载时删除所有文件 自 2009 年以来似乎有了一些进展 来自文档 http developer andro
  • 尝试在节点 0.12 上重新安装 `node-sass`?

    我想使用谷歌网络入门套件 我安装了node js v0 12 0 node sass gulp 然后跑 sudo npm install 当我打字时gulp serve然后得到这个错误 Using gulpfile web starter
  • 将静态库合并为单个

    如何将静态库合并为一个 我确实有三个静态库 libSignatureLibary armv6 a libSignatureLibary armv7 a 和 libSignatureLibary i368 a 现在我想将这三个文件合并到一个库
  • 如何构建 if 语句并与各种值进行比较?

    我该怎么写这个if以更好的方式声明条件 if data in 8 downto 1 x 70 or data in 8 downto 1 x 69 or data in 8 downto 1 x 72 or data in 8 downto
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使
  • 想要定制django Rest框架Browsable API页面

    问题 我想自定义 django Rest Framework Browsable API 页面 使其具有与我的 Web 应用程序的其余部分相同的外观和感觉 安装的软件 Python 3 6 Django 1 10 6 Django 休息框架
  • 检查php中位字段是否打开的正确方法是什么

    检查位字段是否打开的正确方法是什么 在 php 中 我想检查来自 db mysql 的位字段是否打开 这是正确的方法吗 if bit 1 还有其他方法吗 我看到有人使用代码ord http jameslow com 2008 08 12 m
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • CSS:缩放字体大小以适应父块元素的高度

    我发现的几乎每个问题和答案都谈到了视口大小 这确实不是我的问题 拿着这支笔 https codepen io njt1982 pen pZjZNM https codepen io njt1982 pen pZjZNM 我有一个非常基本的
  • 如何在Windows上正确使用node.js child_process.spawn()重定向?

    我有一个干净的 Windows 8 1 盒子 安装了最新的 node js v0 10 29 我在两个文件中有以下测试代码 a js var sub require child process spawn node b js silent
  • 如何检测用户是否禁用 GPS(Android - Play 服务)

    我使用 gms location LocationListener Google Play 服务 来获取用户的位置 它工作正常 但我想检测用户何时禁用或启用他 她的 GPS 就像这张照片一样 当我打开 关闭位置时 不会调用任何方法 当我切换
  • 如何处理两个 gradle 插件的任务冲突?

    我使用 gradle 和两个插件com jfrog artifactory and io swagger core v3 swagger gradle plugin 现在我想按照此处所述进行配置https github com swagge
  • 创建带有部分的选项卡式侧边栏 WPF

    我正在尝试创建一个带有部分的选项卡式侧边栏 如 WPF 中的以下内容 我考虑过几种方法 但是有没有更简单 更优雅的方法呢 方法一 列表框 Using a ListBox并将 SelectedItem 绑定到右侧内容控件所绑定的值 为了区分标
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D
  • 如何使用NetLogo发送参数?

    我对 NetLogo 还很陌生 这就是我被困在这里几周的原因 我想做的是让特工分成 2 队 4 人一组 我的计划是让一个函数保存 4 个海龟 ID to assign groupmates a1 a2 a3 a4 并将他们分配到团队 1 a
  • Libgdx 和 Google 应用内购买结果

    我遵循了这些指示 https github com libgdx libgdx wiki Interfacing with platform specific code使用 ActionResolver 接口集成 Libgdx 和原生 An
  • 添加两个 ActiveRecord::Relation 对象[重复]

    这个问题在这里已经有答案了 如何将两个关系添加在一起 当我尝试 运算符时 它返回一个数组 但我需要它来返回关系 谢谢 麦克风 Try new relation relation merge another relation
  • Tensorflow Eager Execution 不适用于学习率衰减

    在这里尝试让一个热切的执行模型与 LR 衰减一起工作 但没有成功 这似乎是一个错误 因为学习率衰减张量似乎没有更新 如果我遗漏了什么 你可以帮我一下吗 谢谢 下面的代码正在学习一些词嵌入 但是 那学习率衰减部分根本不起作用 class Wo
  • 如何过滤 Solr 中多值字段返回的值

    我有一个文档 其中包含一个名为 uuid 的字段 该字段是一个列表 多值 每个文档最多可以有 100k 个值 例如 我想搜索与以 5ff6115e 开头的 uuid 匹配的文档 我已经可以通过使用成功做到这一点q uuids 5ff6115
  • 搜索引擎如何找到相关内容? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Google 在解析网络时如何找到相关内容 例如 Google 使用 PHP 原生 DOM 库来解析内

随机推荐