【问题标题】:iOS ARC Not deallocating viewsiOS ARC 不释放视图
【发布时间】:2023-03-13 04:17:01
【问题描述】:

我们正在创建一个带有主菜单的应用程序,您可以从中导航到带有后退按钮的第二个视图和大约 6 个其他按钮,这些按钮将 6 个不同的子视图加载到内存(数组)中,具体取决于您选择的那个。

当用户选择“后退”按钮时,我想用 6 个按钮从内存中擦除分配给屏幕的所有内容。

目前,应用程序只是建立内存,似乎没有任何东西被释放。 请看下面网址中的截图:

http://oi41.tinypic.com/jfi8ma.jpg

 //Load all tab views into memory before loading them into an array
TimeViewController *timeView = [[TimeViewController alloc]init];
LocationViewController *locationView = [[LocationViewController alloc]init];
DropOffViewController *dropOffView = [[DropOffViewController alloc]init];
CompanyViewController *companyView = [[CompanyViewController alloc]init];
PaymentViewController *paymentView = [[PaymentViewController alloc]init];

//Set delegates of the tab views
timeView .delegate = self;
locationView.delegate = self;

//Load all tab views into array
[tabViews insertObject:timeView atIndex:0];
[tabViews insertObject:locationView atIndex:1];
[tabViews insertObject:dropOffView atIndex:2];
[tabViews insertObject:companyView atIndex:3];
[tabViews insertObject:paymentView atIndex:4];

for(int x = 0; x<5;x++)
{
    UIViewController *tempView = [[UIViewController alloc]init];
    tempView = [tabViews objectAtIndex:x];
    
    [self addChildViewController:tempView];
}

【问题讨论】:

  • 您是否将您的委托声明为弱属性?
  • 不,如果我将代理设置为弱属性,我会收到以下错误:错误:“__weak 属性‘delegate’的现有实例变量‘_delegate’必须是__weak”
  • 如果您的代表被保留,那么您有retain cycle
  • 谢谢,您知道如何在项目中避免循环吗?我认为这与我在视图控制器 B 中将对象加载到内存中的方式有​​关?
  • 例如,不要保留代表。

标签: ios objective-c memory memory-management


【解决方案1】:

您创建了一个保留周期。

您将委托声明为强属性。这意味着当你这样做时

timeView .delegate = self;

timeView 保留self

当您将timeView 作为子视图控制器添加到self 时,self 将保留timeView

如果self 持有对tabViews 的强引用,那么它是tabViews 的所有者,它是添加到它的对象的所有者,这会产生另一个保留循环:self 拥有tabViews,它拥有@ 987654335@ 拥有self

如果您不想保留循环,则您的子对象绝不能持有对其父母或任何父母的父母的强引用。永远不要将委托声明为强属性。

至于你的“must be __weak”错误,请看this answer

【讨论】:

  • 谢谢,我现在已将所有代表设置为弱,但它仍然保留在某个地方。你知道这可能在哪里吗?感谢您迄今为止的帮助。
  • 我怎么知道?这是委托的常见错误,但这不是创建保留循环的唯一方法。
  • 这是我的内存配置文件的另一个屏幕截图,显示了占用最多内存的内容,也许这可以帮助识别问题:oi39.tinypic.com/2iligbo.jpg
【解决方案2】:

尝试使用此代码清除后退按钮操作时的记忆

for(UIView *view in self.view.subviews)
{
    [view removeFromSuperView];
    view=nil;
}   

【讨论】:

  • 将某些东西设置为 nil 并强制解除分配,它看起来不错。
  • 但我认为当你删除视图时,它会释放内存。
  • 如果有其他东西保留它们,例如他在示例代码中显示的数组,则不会。
  • 如果我们也释放数组呢??
  • 我尝试将数组设置为 nil,这对我没有任何作用,我的一个子视图中有一个 Datepicker 组件,它占用了大部分内存,所以我知道子视图是即使在我将数组设置为 nil 后仍然在内存中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多