【发布时间】:2014-07-04 16:31:01
【问题描述】:
我遇到过由块保留周期引起的内存泄漏。我只想要一个简单的规则,我可以将其应用于我的代码以确保我避免它们。另一方面,我不想在没有必要的情况下将我的代码库库的一半更新为__weak 指针。
这是我目前所拥有的:
使用以下内容时不会出现内存泄漏:
dispatch_async(queue, ^{...}); // GCD call.
[Foo bar:^{...}]; // Class "+" methods with completion block.
但是,这些情况肯定会导致块保留周期内存泄漏:
self.myPropertyBlock = ^{ self; };
_myInstanceVariableBlock = ^{ self; };
self.myPropertyBlock = ^{ _selfInstanceVariable; };
obj.myPropertyBlock = ^{ obj; };
这些情况可能会或可能不会导致块保留周期内存泄漏(取决于块调用对象是否保留块):
[self bar:^{ self; }];
[self.myPropertyObj bar:^{ self; }];
[self.myPropertyObj bar:^{ _selfInstanceVariable; }];
[obj bar:^{ obj; }];
[obj.myPropertyObj bar:^{ obj; }];
为了绝对确定不会发生内存泄漏,有问题的情况需要将块内使用的self 或obj 指针更改为__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; };
请提醒我以上任何错误情况。
有没有更简单更好的规则?
如果你能添加一点解释来解释为什么规则有效或无效,那就太棒了。
基于答案的规则:考虑块中提到的所有对象并询问,这些对象中是否有任何对象保留此块?
【问题讨论】:
标签: ios objective-c memory-leaks objective-c-blocks