0

我有两个视图控制器,一个带有按钮网格,第二个是基于用户按下的按钮的详细描述。

我在 Instruments 分配工具中使用“Mark Heap”,并在用户看到详细的视图控制器然后按下导航栏中的后退按钮后发现我的应用程序的内存正在增加。它应该导致内存的净变化为零......我正在使用ARC,xcode 4.2.1,部署到ios 5.0+

当我在按下按钮后加载新的 ViewController 时,我在后台线程中加载了一些数据图像。是否有可能因为我快速按下后退按钮,数据仍在后台线程中加载并且永远不会从内存中释放?

4

1 回答 1

0

从班级的幻灯片中,我描述了您可能面临的内存周期问题:

如果你有一个类的以下属性怎么办?

@property (strong, nonatomic) NSArray* myBlocks;    // array of blocks

然后尝试在该类的方法之一中执行以下操作?

[self.myBlocks addObject:^() {
    [self doSomething];
}];

块内引用的所有对象都将保留在堆中,只要该块存在。(换句话说,块保留了指向其中引用的所有对象的强指针。)

在这种情况下,self 是此块中引用的对象。因此该块将有一个指向自身的强指针。但请注意 self 也有一个指向块的强指针(通过它的 myBlocks 属性)

这是一个严重的问题!

现在,无论是 self 还是 block 都无法逃离堆。那是因为总会有一个指向它们的强指针(彼此的指针)。这称为记忆“循环”。

解决方案:

局部变量总是很强大。没关系,因为当它们超出范围时,它们就会消失,所以强指针消失了。但是有一种方法可以声明局部变量是弱的。就是这样 ...

__weak MyClass* weakSelf = self;
[self.myBlocks addObject:^{
    [weakSelf doSomething];
}];

这解决了问题,因为现在该块只有一个指向自身的弱指针。(self 仍然有一个指向 block 的强指针,但这没关系)只要宇宙中的某个人有一个指向这个 self 的强指针,block 的指针就是好的。并且如果 self 不存在,则该块将不存在(因为 myBlocks 将不存在),一切都很好!

于 2012-07-20T00:03:16.377 回答