gpt4 book ai didi

ios - View Controller 的 NSMutableArray 不释放其对象的内存

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

这基本上与我的另一个问题有关 here

我正在尝试释放 NSMutableArray其中包含 View Controller 。我做:

self.viewControllers = nil;

viewWillDisappear因为我正在转向另一个 View 。但无论我做什么, View Controller 都不会被释放。我也试过:
[[scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

其中 scrollview 是拥有包含 NSMutableArray 的 View .

尽管包含 NSMutableArray 的引用计数,但我看到实时 View Controller (在仪器中)的计数没有改变是 0。

最佳答案

几个观察:

  • 确保通过静态分析器运行非 ARC 代码。这可以找到许多困扰非 ARC 代码的内存管理问题。从 Xcode 的“产品”菜单中选择“分析”,或按 command+shift+B。如果您使用 ARC,许多这些内存管理问题就会消失,但如果您不使用 ARC,静态分析器在检查您的代码时可能是无价的。
  • 您的尝试 removeFromSuperview是不必要的,不会影响retainCount View Controller 本身。不过,我是否从这次尝试中推断出您已经创建了 View Controller ,然后将它们的 View 添加到 ScrollView 中?如果是这样,您是否做了必要的工作 addChildViewController对于每一个?如果是这样,您确实需要执行相关的 removeFromParentViewController不过,对于其中的每一个。
  • View Controller 的正确释放取决于您如何定义和分配 viewControllers数组,以及如何填充它。

    但是,例如,我有一个属性:
    @property (nonatomic, retain) NSMutableArray *array;

    我用下面的代码初始化它(注意 autorelease 本身的 NSMutableArray(因为我使用的访问器方法会为我保留它),以及 release 对象的显式 Object) :
    - (void)makeArray
    {
    // create an array, using the accessor method (thus why I'm using an autorelease object)

    self.array = [[[NSMutableArray alloc] init] autorelease];

    // just add four random objects to the array.
    // note, adding them to the array increases their retain count, thus I
    // release them to bring the retain count back to +1 ... I could have
    // done that via autorelease, too

    for (NSInteger i = 1; i < 4; i++)
    {
    Object *obj = [[Object alloc] initWithString:[NSString stringWithFormat:@"Test %d", i]];
    [self.array addObject:obj];
    [obj release];
    }
    }

    如果我检查 retainCount值,我可以看到一切都有 retainCount +1,视情况而定:
    - (void)logArray
    {
    // let's examine the retain counts for the objects in the array
    // should be "1" given there are no other strong references anywhere

    for (id obj in self.array)
    NSLog(@"%s %@ (retainCount = %d)", __FUNCTION__, obj, [obj retainCount]);

    // let's also examine the retain count for the array, itself
    // this should also be "1"

    NSLog(@"%s retainCount = %d", __FUNCTION__, [self.array retainCount]);
    }

    当我在以下方法中清除它时,它(和数组的各个对象)被正确释放(事实证明 Object 类在其 NSLog 方法中执行了 dealloc):
    - (void)clearArray
    {
    // let's use the accessor method to release the array and make sure
    // the pointer is nil

    self.array = nil;
    }
  • 这是一种冗长的说法,说明您的 self.viewControllers = nil; 语法是一种非常适合释放数组(及其成员对象)的方法,假设数组定义为 retain属性如上一点所示。但是,如果数组的成员对象没有被释放,那么这些对象显然没有得到它们的 retainCount降到零。我会尝试,就在您的 self.viewControllers = nil; 之前,记录不仅retainCount数组本身,还有 retainCount阵列的单个对象,以确认它们的 retainCount设置。

    他们都应该有一个 retainCount在那一点上+1(否则还有其他东西保留它们,要么因为它们被过度保留,你在这些 View Controller 中有一些保留周期(又名强引用周期),或者其他东西合法地保留它们(例如在某些时候,您将这些 View Controller 之一推送到导航器堆栈上,但您还没有将它们弹出))。
  • 如果您仍然泄漏,我将使用 Instruments 到 find the leak .顺便说一下,当检查调用树的泄漏时,我发现“反转调用树”和“隐藏系统库”很有用。


  • 更新:

    在上面的第 4 点中,我警告了保留周期的风险。保留循环的一个例子是使用 NSTimer由 View Controller 和失败 invalidaterelease需要释放 View Controller 的计时器。与您离线聊天,这听起来可能是您尝试 release 的问题所在。 NSTimerdealloc ,但 dealloc永远不会调用,因为计时器本身保留了 View Controller 。您需要手动 invalidaterelease NSTimer (通过释放对 View Controller 的强引用)在您释放 NSMutableArray 之前具有计时器的任何 View Controller 。 . (例如,可能有一个停止计时器的协议(protocol),让您的 subview Controller 符合该协议(protocol)。)

    关于ios - View Controller 的 NSMutableArray 不释放其对象的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13328949/

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