NSArray收到了内存警告

时间:2014-01-02 22:54:15

标签: ios memory memory-leaks nsarray

按下按钮时,我有一组图像变为随机图像并且IBAction附加到按钮上。在模拟器上运行它运行正常,但在设备上它似乎在内存警告后崩溃。按下按钮时也会滞后。我希望它能够顺利运行,而不是崩溃。我相信这与我的阵列没有释放每个图像有关。这是我的按钮代码中的数组。

-(IBAction)buttonPressed:(id)sender;
{

     int ptr = arc4random() % 132;

    NSArray* images = [[NSArray alloc] initWithObjects:@"17",@"29",@"55",@"400",@"Alcohol",@"Arianny",@"Anderson",@"Approach",@"Arab",@"Asian",@"Attitude",@"Attraction",@"Beckinsale",@"Blueberry",@"Brain",@"Break",@"Breakups",@"Burns",@"Buttocks",@"Charity",@"Check",@"Chicago",@"Chocolate",@"Coco",@"Coffee",@"College",@"Commit",@"Common",@"Confident",@"Cook",@"Count",@"Country",@"Couples",@"Courtship",@"Criminal",@"Cruz",@"Date",@"Date14",@"Deed",@"Degree",@"Dropped",@"Dushku",@"Dworaczyk",@"Eating",@"Emotion",@"Exercise",@"Fwb",@"Fantasies",@"Fitness",@"Flings",@"Flirt",@"Foot",@"Forget",@"Friendship",@"Frowning",@"Hum",@"Impression",@"Hair",@"Happiness",@"Hazel",@"Headache",@"Instant",@"Interest",@"Internet",@"Jacobs",@"January",@"Jimena",@"Jolie",@"Kalia",@"Kardashian",@"Kiss",@"Kissing",@"Krupa",@"Larissa",@"Latino",@"Laughter",@"Lip",@"London",@"Love",@"Love2",@"Love3",@"Love4",@"Math",@"Maximus",@"Melany",@"Memory",@"Men",@"Milian",@"Miller",@"Millions",@"Mind",@"Monica",@"Muscle",@"Partner",@"Naps",@"Negativity",@"Novels",@"Oral",@"Ossa",@"Pain",@"Positions",@"Productive",@"Proximity",@"Read",@"Reputation",@"Second",@"Sensitive",@"Serious",@"Shaking",@"Sleep2",@"Smile",@"Smoke",@"Smoke2",@"Smokers",@"Sneeze",@"Socks",@"Sold",@"Spot",@"Stimuli",@"Stone",@"Survey",@"Swell",@"Tattoo",@"Teacher",@"Teeth",@"Vickers",@"Violence",@"Wallet",@"Weight",@"Windmills.png",@"White",@"Women",@"Yawn",nil];


    [imageView setImage:[UIImage imageNamed:[images objectAtIndex:ptr]]];
    ptr++;
    NSLog(@"button pressed");

}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.images=nil;

}

- (void)dealloc {

    [images release];
    [adView release];

    [super dealloc];
}

3 个答案:

答案 0 :(得分:2)

因为我看到您的代码没有使用ARC运行所以当您创建图像阵列时,在您调用release之前不会从内存中删除它。在您不再需要阵列后写入发布:

int ptr = arc4random() % 132;
NSArray* images = [[NSArray alloc] initWithObjects:@"17",@"29"];
[imageView setImage:[UIImage imageNamed:[images objectAtIndex:ptr]]];
ptr++;
[images release];

答案 1 :(得分:1)

首先,如果可以,请使用ARC。

你有两件事泄漏记忆:图像和图像名称数组。由于图像名称是常量,因此您只需创建一次此数组。

为图像和图像名称数组创建ivars:      UIImage * _image;      NSArray * _imageNames; //在viewDidLoad:

中初始化

然后,按下按钮处理程序:

-(IBAction)buttonPressed:(id)sender;
{
     int ptr = arc4random() % 132;

    [_image release];
    _image = UIImage imageNamed:_images[ptr]];
    [imageView setImage:_image];
    ptr++;
    NSLog(@"button pressed");
}

最后,发布_imageNames:

- (void)dealloc
{
    [_imageNames release];
    // release everything else.
}

同样,您应该考虑切换到ARC。你会很高兴的。

答案 2 :(得分:1)

你实际上有两个问题,围绕这一行:

NSArray* images = [[NSArray alloc] initWithObjects: ...strings omitted... ,nil];

首先,行开头的NSArray*声明了一个新的局部变量images。这与您尝试在self.images中删除并在-viewDidUnload中发布的属性-dealloc分开。从行中删除NSArray*将解决此问题,将数组存储到您想要的self.images属性中。

这给你一条这样的一句话:

images = [[NSArray alloc] initWithObjects: ...strings omitted... ,nil];

第二个问题是每次执行此方法时都会重新创建images数组。这意味着,即使您修复了第一个问题,每次通过该方法时,仍然会丢弃旧数组而不释放它,因此您仍然会泄漏这些数组。有很多方法可以解决这个问题,但最简单的方法可能只是测试你是否已经有一个数组,只有你没有才能创建它:

if(!images) {
    images = [[NSArray alloc] initWithObjects: ...strings omitted... ,nil];
}

(由于此类的所有实例都有相同的图像名列表,您可以将数组存储在静态变量中,以便在它们之间共享 - 可能通过调用dispatch_once进行初始化 - 但这不是除非你同时在屏幕上有很多这种视图控制器的实例,否则可能会有所不同。)