8

有一个有趣的问题,即在 XIB 布局(UIScrollView 的子类)中引用了一个类,并且没有根据 Instruments / Allocations 取消分配并且不会中断它的 dealloc 例程。我们称它为 Sclass1。

有一个使用类(我们称之为 Uclass),它具有 XIB 文件和插座。

@property (nonatomic, weak) IBOutlet Sclass1* sclass1;

这与 XIB 文件布局正确挂钩。

Sclass1 是加载 Uclass 的 XIB 时分配的属性。Uclass 确实会被释放,然后不时重新创建,因此我们有另一个 Sclass1 实例,但 Sclass1 永远不会消失,也找不到对它的另一个引用。

在 Instruments 中向下钻取显示了一个 Malloc,就是这样。

仅供参考,课程开始于

[UIClassSwapper initWithCoder:]
4

4 回答 4

5

如果一个对象在 ARC 下没有被释放,则意味着存在对它的强引用。由于您的属性是weak该对象必须由 Uclass 对象以外的其他对象强烈拥有(否则它将在 XIB 加载后立即被释放)。在您提供的代码中,不清楚该对象的实际强所有者是什么,但我认为它可能是以下一个(或多个):

  1. 由于对象的类是UIView子类,superview如果添加为subviews. 这会在加载 XIB 文件时自动发生。如果superview没有被释放,SClass对象也不会。您可以通过调用删除此所有权removeFromSuperview
  2. 在对象的 ivars 之间的某个地方存在一个强所有权周期(保留周期)SClass1(即,其中一个强所有权实例变量对其所有者具有强引用 - the SClass1)。请注意,任何self直接使用的块也会保持强引用。对块的强引用通常会导致保留周期。保存self__weakvar 并将其传递给块,除非您有充分的理由不这样做。
  3. 通过例如将对象添加到容器或将指针保存到非__weak变量来存在手动创建的强引用。

尝试找到并删除这些强大的所有权。只有在所有这些都被删除之后,才能释放对象。

于 2013-10-08T14:52:45.237 回答
1

由于您的属性很弱且仍未解除分配,因此请查找对 Sclass 或其所有者 Uclass 的强引用。也许您直接在块中使用 Uclass(或 Sclass),没有 __weak typeof(self) weakSelf 跳舞,这个块创建保留循环。还要注意亲子关系和代表。也许有一个强而不是弱的委托,或者两个控制器对彼此有强引用。

另外,如果您想获得更详细的答案,请发布更多相关代码。

于 2013-10-11T09:38:21.717 回答
0

我认为你@property应该对一个班级很坚强:

@property (nonatomic, strong) IBOutlet Sclass1* sclass1;

因为strong相当于retain和ARC会为你管理发布。

您将在有关属性属性部分的 Apple 文档中获得有关过渡到 ARC 发行说明的更多信息。

于 2013-10-07T07:55:43.093 回答
0

我最近有同样的症状 - 为了解决我的问题,我的对象充当了许多其他对象的委托,因此必须在调用 dealloc 之前释放对象的所有委托职责

于 2014-01-27T23:20:52.217 回答