【问题标题】:Storing and Retrieving Custom Object (ARC) Keeps growing memory存储和检索自定义对象 (ARC) 保持不断增长的内存
【发布时间】:2017-07-17 07:19:48
【问题描述】:

希望有人能对这个问题有所了解。

我正在使用 NSCoding + NSUserDefaults 检索自定义对象数组,每次重新加载视图时,内存都会继续增长。

这是我用来检索自定义对象数组的代码(在 ViewDidLoad 下调用:

NSData *dataRepresentingSavedArray;

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
dataRepresentingSavedArray = nil;
dataRepresentingSavedArray = [currentDefaults objectForKey:@"women"];
if (dataRepresentingSavedArray != nil)
{
    NSArray *oldSavedArray = nil;
    oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
    if (oldSavedArray != nil)
        women = [[NSMutableArray alloc] initWithArray:oldSavedArray];
    else
        women = [[NSMutableArray alloc] init];
}

woman.backgroundimage 是导致内存损失最多的原因,但是当我从自定义对象和 NSCoder 中完全删除该方面时,它仍然在内存中攀升而没有释放,但速度较慢。 ViewController 是导航控制器 (SWRevealViewController Pod) 的一部分,当它被选中时,内存会增加,直到应用程序崩溃。感谢您的宝贵时间!

编辑:我想我还应该分享数据的存档方式。首先压缩图片:

                 CGFloat maxCompressionFactor = 0.1f;
                 CGFloat compressionFactor = 0.9f;
                 int maxImageSize = 60 * 1024;

                 NSData *imageData = UIImageJPEGRepresentation(_theimage, compressionFactor);

                 while ([imageData length] > maxImageSize && compressionFactor > maxCompressionFactor)
                 {
                     compressionFactor = 0;
                     imageData = UIImageJPEGRepresentation(_theimage, compressionFactor);
                 }

                 _theimage = [UIImage imageWithData:imageData];
                 _theimage = [self scaleImage:_theimage toSize:CGSizeMake(320.0,480.0)];

然后存储所有值:

 //store to woman object
                 Woman* woman = [[Woman alloc] initWithFull:nameOfGirl withdate2:date withintervalLength:string  withperiodLength:[NSString stringWithFormat:@"432000"] withpmsLength:[NSString stringWithFormat:@"432000"]initWithbackground:_theimage];

                 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

                 [women addObject:woman];

                 [userDefaults synchronize];

【问题讨论】:

  • 女性可变数组在哪里声明?
  • 感谢您的评论,我在 .h 中将其声明为 @property (nonatomic) NSMutableArray *women;
  • 我不喜欢你用一个全新的数组替换一个 VC 属性 (women)。您正在更改 women 指向的内存位置。为什么不使用[women setArray:oldSavedArray]?然后,如果视图或视图控制器中的某些内容保留了women,那么您至少不会拥有之前的women 对象。不幸的是,这并不能解决任何可能在数组中保留对象的问题。我会尽量避免替换支持视图对象的数据模型对象,而不删除旧的视图对象。我认为视图或控制器保留了一些东西
  • 这里真正的问题是有一个视图或控制器对象保留了一些旧的东西,您想用新数据替换它们。但是你的allocs 正在加剧这个问题,因为每个alloc 都会创建另一个可以变成僵尸的对象。另一方面,如果您基本上使用 API 等效于对取消引用的属性进行赋值,您仍然可以保留该对象,但至少您还没有创建新对象。
  • 当视图变为非活动状态时,我会开始尝试将所有内容清零,并将清零包装在 autoreleasepool 外壳中。 3 年前我在 OSX 上做过这种工作,但你可以at least get this gist of it here

标签: objective-c nsmutablearray nsuserdefaults nscoding custom-object


【解决方案1】:

这个答案只是cmets的概要。

了解正在发生的事情的关键是某些对象(可能是视图控制器本身,但也可能是自定义视图对象,无论如何)保留了您从 NSUserDefaults 创建的对象。

我们减少了allocs 的数量,内存增长量也减少了,这似乎证实了每次ViewDidLoad 被命中时,都会创建一个对象但从未解除分配,因为它的保留计数从未达到零。其他一些留在内存中的对象保持对它的强引用。

那时,我只是建议在右视图生命周期函数 (viewDidDisappear?) 中进行积极的 nil 分配,并将其包裹在 @autoreleasepool 外壳中以防万一。事实证明,这完全解决了问题。

nil 分配给VC 中的属性可确保strong 属性的数据在VC 本身被释放之前不会保留在内存中。使用 @autoreleasepool 告诉 ARC 释放零引用计数对象,这些对象在外壳终止时在外壳内变为零引用计数。我将“池”视为机箱内引用计数交易的分类帐。外壳保留自己的 ARC 账簿,并在完成后清除其分类帐。

【讨论】:

    猜你喜欢
    • 2016-10-25
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 2017-02-17
    • 2015-04-02
    相关资源
    最近更新 更多