单视图IOS 7内存泄漏

时间:2014-08-25 17:38:09

标签: ios objective-c memory-leaks xcode5

我正在尝试编写一个简单的ios7单视图应用程序。视图控制器具有占据整个屏幕的UI图像视图,其中两个按钮占据屏幕的整个左侧和右侧。从本质上讲,我希望能够通过单击右侧显示下一个连续图像来滚动图像数组,并且左侧显示前一个连续图像。

这个应用程序有效,但似乎我的按钮代码中的指针没有被解除。或者其他什么,我不太确定。每次我进入一个新页面时,都会有越来越多的内存堆积,直到它运行超过700mb RAM。请帮助我更好地理解这个内存分配问题。运行项目的配置文件后,似乎所有内存都被"所有匿名虚拟机"

使用

以下是视图控制器的代码。

#import "ABCViewController.h"
#import "ABCPage.h"

@interface ABCViewController ()

@end

@implementation ABCViewController

int current = 0;

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ABCPage *A = [[ABCPage alloc] init];
A.picture = [UIImage imageNamed:@"a.png"];
ABCPage *B = [[ABCPage alloc] init];
B.picture = [UIImage imageNamed:@"b.png"];
ABCPage *C = [[ABCPage alloc] init];
C.picture = [UIImage imageNamed:@"c.png"];
ABCPage *E = [[ABCPage alloc] init];
E.picture = [UIImage imageNamed:@"e.png"];
ABCPage *F = [[ABCPage alloc] init];
F.picture = [UIImage imageNamed:@"f.png"];
ABCPage *G = [[ABCPage alloc] init];
G.picture = [UIImage imageNamed:@"g.png"];
ABCPage *H = [[ABCPage alloc] init];
H.picture = [UIImage imageNamed:@"h.png"];
ABCPage *I = [[ABCPage alloc] init];
I.picture = [UIImage imageNamed:@"i.png"];
ABCPage *J = [[ABCPage alloc] init];
J.picture = [UIImage imageNamed:@"j.png"];
ABCPage *K = [[ABCPage alloc] init];
K.picture = [UIImage imageNamed:@"k.png"];
ABCPage *L = [[ABCPage alloc] init];
L.picture = [UIImage imageNamed:@"l.png"];
ABCPage *M = [[ABCPage alloc] init];
M.picture = [UIImage imageNamed:@"m.png"];
ABCPage *N = [[ABCPage alloc] init];
N.picture = [UIImage imageNamed:@"n.png"];
ABCPage *O = [[ABCPage alloc] init];
O.picture = [UIImage imageNamed:@"o.png"];
ABCPage *P = [[ABCPage alloc] init];
P.picture = [UIImage imageNamed:@"p.png"];
ABCPage *Q = [[ABCPage alloc] init];
Q.picture = [UIImage imageNamed:@"q.png"];
ABCPage *R = [[ABCPage alloc] init];
R.picture = [UIImage imageNamed:@"r.png"];
ABCPage *S = [[ABCPage alloc] init];
S.picture = [UIImage imageNamed:@"s.png"];
ABCPage *T = [[ABCPage alloc] init];
T.picture = [UIImage imageNamed:@"t.png"];
ABCPage *U = [[ABCPage alloc] init];
U.picture = [UIImage imageNamed:@"u.png"];
ABCPage *V = [[ABCPage alloc] init];
V.picture = [UIImage imageNamed:@"v.png"];
ABCPage *W = [[ABCPage alloc] init];
W.picture = [UIImage imageNamed:@"w.png"];
ABCPage *X = [[ABCPage alloc] init];
X.picture = [UIImage imageNamed:@"x.png"];
ABCPage *Y = [[ABCPage alloc] init];
Y.picture = [UIImage imageNamed:@"y.png"];


self.myBook = [[NSMutableArray alloc] init];
[self.myBook addObject:A];
[self.myBook addObject:B];
[self.myBook addObject:C];
[self.myBook addObject:E];
[self.myBook addObject:F];
[self.myBook addObject:G];
[self.myBook addObject:H];
[self.myBook addObject:I];
[self.myBook addObject:J];
[self.myBook addObject:K];
[self.myBook addObject:L];
[self.myBook addObject:M];
[self.myBook addObject:N];
[self.myBook addObject:O];
[self.myBook addObject:P];
[self.myBook addObject:Q];
[self.myBook addObject:R];
[self.myBook addObject:S];
[self.myBook addObject:T];
[self.myBook addObject:U];
[self.myBook addObject:V];
[self.myBook addObject:W];
[self.myBook addObject:X];
[self.myBook addObject:Y];

self.imageView.image = A.picture;

}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (IBAction)previousButton:(UIButton *)sender
{

if (current > 0) {
current--;
ABCPage *currentPage = [self.myBook objectAtIndex:current];
self.imageView.image = currentPage.picture;
}

}

- (IBAction)nextButton:(UIButton *)sender
{
if (current < 23) {
current++;
ABCPage *currentPage = [self.myBook objectAtIndex:current];
self.imageView.image = currentPage.picture;
}

}
@end

2 个答案:

答案 0 :(得分:0)

它的工作方式是,只要将ABCPage放入myBook数组,阵列就会在ABCPage上执行+1;这个'retain'将停止释放对象。您的页面引用图像,因此图像不会被取消分配。此外,当您将页面的图像分配给self.imageView时,它在设置的持续时间内变为+2。

如果我没记错的话,你需要告诉持有图像视图的视图需要用

更新
[self.view setNeedsDisplay]

否则屏幕不会显示新图像。

匿名VM内存高的原因在于,对于每个UIImage,VM子系统分配的对等存储区域用包含图像数据的存储器“后退”图像。释放UIImage时,释放对等内存。

进行调整以减少内存,同时保持质量和速度平衡良好是棘手的。我建议首先通过每次需要时加载图像来尝试它,并且没有数组来提前存储它们。这意味着当您经历时,您将为每个图像执行+1和-1。我会在每次更改页面后发出setNeedsDisplay。你需要首先了解内存泄漏,然后从那里开始工作。

听起来这些图片对于内存而言都太大了,因此您目前所在页面附近的图片可能需要缓存。这可能是您的下一步。

答案 1 :(得分:-1)

您可以将UICollectionView与自定义单元格一起使用,它可以更好地适应这种特定情况。

UICollectionViews有一个称为可重用单元的东西,这意味着它不会保留在未被使用的内存单元中。并且它将在可能的情况下重用现有的。如有必要,它只会创建新的。

UICollectionView有一种类似的方式来处理UITableView这个非常笼统的术语。

查看UICollectionView的文档,即使您可以进一步向下并向您的应用添加滑动手势识别器,这是在水平排列的视图之间切换的常用方法。

https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionView_class/Reference/Reference.html

与内存泄漏相关只是将ABCPage * currentPage设为属性,而不是每次在下一个和上一个实例化它。将它作为类声明中的属性,只需在执行ABCPage * currentPage时分配它即可创建新实例,并且您提到的内容不会从内存中释放。