gpt4 book ai didi

ios - 避免 Objective-C block 保留周期内存泄漏的简单规则是什么?

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

我曾经遇到过 block 保留周期引起的内存泄漏。我只想要一个简单的规则,我可以将其应用于我的代码以确保我避免它们。另一方面,我不想在没有必要的情况下将一半的代码库更新为 __weak 指针。

这是我目前的情况:

当您使用以下内容时,不会有内存泄漏:

dispatch_async(queue, ^{...}); // GCD call.
[Foo bar:^{...}]; // Class "+" methods with completion block.

但是,这些情况肯定会导致 block 保留周期内存泄漏:

self.myPropertyBlock = ^{ self; };
_myInstanceVariableBlock = ^{ self; };
self.myPropertyBlock = ^{ _selfInstanceVariable; };
obj.myPropertyBlock = ^{ obj; };

这些情况可能会也可能不会导致 block 保留周期内存泄漏(取决于 block 调用对象是否保留 block ):

[self bar:^{ self; }];    
[self.myPropertyObj bar:^{ self; }];
[self.myPropertyObj bar:^{ _selfInstanceVariable; }];

[obj bar:^{ obj; }];
[obj.myPropertyObj bar:^{ obj; }];

为了绝对确定不会有内存泄漏,有问题的情况需要将 block 内使用的 selfobj 指针更改为 __weak 像这样的指针(或其他一些避免泄漏的策略):

__weak SelfClass *weakSelf = self;
self.myPropertyBlock = ^{ weakSelf; };
_myInstanceVariableBlock = ^{ weakSelf; };
self.myPropertyBlock = ^{ weakSelf.instanceVariableConvertedToProperty; };
[self bar:^{ weakSelf; }];
[self.myPropertyObj bar:^{ weakSelf; }];
[self.myPropertyObj bar:^{ weakSelf.instanceVariableConvertedToProperty; }];

__weak ObjClass *weakObj = obj
[obj bar:^{ weakObj; }];
[obj.myPropertyObj bar:^{ weakObj; }];
obj.myPropertyBlock = ^{ weakObj; };

如有以上错误,请提醒我。

是否有更简单更好的规则?

如果您可以添加一些解释来解释规则为何有效或无效,那就太棒了。

基于答案的规则:考虑 block 中提到的所有对象并询问,这些对象中的任何一个都保留了这个 block 吗?

最佳答案

保留周期是 A -> B -> A(其中 -> 表示保留)。这很糟糕,因为我们无法释放保留的东西,所以释放 A 的唯一方法是释放 B,但这取决于释放 A。

block 保留周期没有什么不同,除了 block 在保留方面更积极:它们保留其中引用的任何对象,因此如果 A -> Block 和 Block 提到 A,则 A -> Block -> A。

所有这些都导致了编码 block 时的简单规则。考虑 block 中提到的所有对象并询问,这些对象中的任何一个都保留了这个 block 吗?大多数时候他们没有。但是要特别注意你将 block 传递给的对象,换句话说:

[beSuspiciousOfMe heresABlock:^{
NSLog(@"does %@ retain this block?", beSuspiciousOfMe];
}];

如果您控制 beSuspiciousOfMe(可以是,而且通常是 self),这很容易检查。如果该代码由于某种原因不透明,而您不确定,则可以使用 __weak 复制技巧。

关于ios - 避免 Objective-C block 保留周期内存泄漏的简单规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23691579/

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