gpt4 book ai didi

objective-c - 解除锁定包含 block 的对象

转载 作者:行者123 更新时间:2023-12-03 16:41:46 24 4
gpt4 key购买 nike

首先(因为这个问题与内存管理有关),我不得不说我在 ARC 上运行。

我有一个对象 (MyObject),其中包含 MyProcess 对象的数组。 MyObject 在某个时刻创建一个新的 MyProcess,将其添加到数组中,以 block 的形式为其提供完成处理程序,然后告诉进程启动。

MyProcess* newProcess = [MyProcess new];

[allProcessesArray addObject: newProcess];

newProcess.completionBlock = ^(MyProcess* process){
[allProcessesArray removeObject: process];
// Other things are done here
};

[newProcess start];

现在,在 MyProcess 方面,当调用 start 时,MyProcess 会在内部调用 threadedStart(在后台线程上运行),它会完成其工作,然后在完成时调用该 block :

- (void)threadedStart
{
// Do something

dispatch_async(dispatch_get_main_queue(), ^{ self.completionBlock(self); });
}

完成 block 被定义为 MyProcess 接口(interface)中的一个属性,如下所示:

typedef void(^MyCallbackBlock)(MyProcess* process);
@property (strong) MyCallbackBlock completionBlock;

现在,MyProcess 仅在其生命周期内由 allProcessesArray 保持事件状态,因为该数组是唯一引用该进程的对象。当我在完成 block 上从数组中删除该进程时,我认为该进程会立即解除锁定。然后,由于进程包含该 block 本身,因此该 block 在仍在运行时也会被解除锁定!

我预计这会导致问题,但我已经测试了这段代码并且该 block 运行良好直到最后。现在,有两个选择:要么我的推理是错误的,并且这段代码是完全安全的,要么我是对的(或至少部分正确),但这并不安全,因为它只有时有效。

基本上,我的问题是:这种回调 block 的方法安全吗?如果没有,你能建议一些不同的东西吗?

最佳答案

对于您的 block 属性,它应该是copy,而不是strong。应始终复制 block 。

@property (copy) MyCallbackBlock completionBlock;

运行 block 是否会导致问题取决于运行的代码以及它使用的变量的定义方式。

在 block 内部,由于 myProcess 是在 block 外部定义的,因此它保留在 block 内部。因此,当您从数组中删除它时,它仍然会保留到 block 末尾。

从技术上讲,这可以归类为保留周期的一种形式,但由于其结构,它对您有用。

block 本身在运行时无法“释放”。

<小时/>

对于更新后的代码,实例现在(可能以前是,我只是没有看)由对 block 的调用保留(因为它是作为参数提供的)。同样,该实例将保留到 block 执行结束为​​止。

关于objective-c - 解除锁定包含 block 的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17260011/

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