gpt4 book ai didi

iOS - GCD 对 self 的弱引用和强引用

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:12:17 25 4
gpt4 key购买 nike

当我在 GCD 的一个 block 中时,我总是使用 __weakself 的引用。每个人都建议这样做。我知道在 GCD 中对 self (tested) 的强引用不会产生保留周期。Apple 建议使用 __weak 对 self 的引用,然后使用 __strong_week 的引用以保证 self 在 block 执行时不会是 nil

我有以下代码:

- (IBAction)startGCD:(id)sender {

GCDVC* __weak weakSelf = self;

[self.activityIndicator startAnimating];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1

// VC2* __strong strongSelf = weakSelf;

[weakSelf.proArray addObject:@"2"];

[NSThread sleepForTimeInterval:10];

NSLog(@"%@",weakSelf.proArray);

dispatch_async(dispatch_get_main_queue(), ^{ // 2
[weakSelf.activityIndicator stopAnimating];
});
});

}

测试 1我按下按钮,指示器开始旋转。我在 GCD 完成之前按下后退按钮,GCDViewController 被释放。

测试 2然后我取消对 self 的强引用的注释并执行相同的过程。 GCDViewController 在 block 完成工作之前不会被释放。但后来发布了。

测试 3现在,如果我直接引用 self(没有 __weak__strong),我就会在测试 2 中得到准确的行为。

因此,如果我想确保在 block 执行时 self 不会为 nil,那么使用 __strong 引用到 __weak 引用的意义何在? 自己?我在这里想念什么吗?是否有任何示例会改变测试 2 和 3 的结果?

最佳答案

I was always using __weak references to self when I was in a block in GCD. Everyone recommends that.

没有。我不知道有谁推荐这个。在某些存在循环保留的情况下,弱引用是有意义的。但是一个 block 是否应该捕获对任何对象(包括 self 指向的对象)的弱引用或强引用取决于相关代码的特定内存管理设计和

I know that strong reference to self (tested) in GCD can't produce retain cycles.

将 block 传递给全局或主队列上的 dispatch_async 永远不会产生保留周期。

Now if I refer directly to self (without __weak or __strong) I have the exact behaviour with Test 2.

在这种情况下,您可能看不出有什么不同。但它们通常有不同的行为。基本上,您的问题是捕获对 self 指向的对象的强引用或弱引用的 block 之间有什么区别。

不同之处在于,如果当前对象(self 指向的对象)已被所有其他对它拥有强引用的对象释放,除了可能的 block ,和 block 随后异步执行。

  • 如果该 block 捕获了对当前对象的强引用,那么该引用将使该对象在整个时间内保持事件状态。所以对象仍然存在,我们可以使用它并向它发送消息等。
  • 如果 block 捕获了对当前对象的弱引用,则当前对象已经被释放,当对它的最后一个强引用被释放时。所以此时 block 的弱引用将为 nil,并且 block 不会对其进行任何操作(它要么检查 strongSelf 并在它看到时返回它是 nil,否则它将向 strongSelf 发送消息,nil 什么都不做)。

所以在一种情况下,事情已经完成,而在另一种情况下,什么都没做。

如果你的当前对象是一些 UI 元素,比如 View 或 View Controller ,那么只要它在 View 层次结构中,它就会被 View 层次结构中的事物保留,所以你需要退出此 View / View Controller ,以便出现没有其他任何东西对其有强引用的情况。

在您的情况下,您在 block 内所做的就是 [weakSelf.activityIndi​​cator stopAnimating];,即对 UI 的更改。这个命令是否运行并不重要,因为,记住,包含它的 View 已经停止显示了。没有人可以看到此事件指示器。那么停不停有什么区别呢?但这是特定于这种情况的。通常,您可以想象 block 内的命令会更改某些全局状态,或通过网络发送某些内容或其他内容,执行与否之间存在很大差异。

关于iOS - GCD 对 self 的弱引用和强引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38638904/

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