Ios NSArray收到内存警告

Ios NSArray收到内存警告,ios,memory,memory-leaks,nsarray,Ios,Memory,Memory Leaks,Nsarray,我有一组图像,当按下按钮时,这些图像会变成随机图像,并在按钮上附加一个iAction。在模拟器上运行时,它运行良好,但在设备上,它似乎在内存警告后崩溃。按下按钮时,它也会滞后。我希望它运行平稳,而不是崩溃。我相信这与我的阵列没有发布每个图像有关。这是我的按钮代码中的数组 -(IBAction)buttonPressed:(id)sender; { int ptr = arc4random() % 132; NSArray* images = [[NSArray alloc]

我有一组图像,当按下按钮时,这些图像会变成随机图像,并在按钮上附加一个
iAction
。在模拟器上运行时,它运行良好,但在设备上,它似乎在内存警告后崩溃。按下按钮时,它也会滞后。我希望它运行平稳,而不是崩溃。我相信这与我的阵列没有发布每个图像有关。这是我的按钮代码中的数组

-(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];
}

正如我看到的,您的代码没有使用ARC运行,所以当您创建images数组时,它不会从内存中删除,直到您调用release。在不再需要阵列后编写版本:

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

正如我看到的,您的代码没有使用ARC运行,所以当您创建images数组时,它不会从内存中删除,直到您调用release。在不再需要阵列后编写版本:

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

首先,如果可以,使用ARC

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

为映像和映像名称数组创建IVAR: UIImage*\u图像; 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

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

为映像和映像名称数组创建IVAR: UIImage*\u图像; 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.
}

再次,你应该考虑切换到弧。你会很高兴你这么做的。

你实际上有两个问题,都围绕着这条线:

NSArray* images = [[NSArray alloc] initWithObjects: ...strings omitted... ,nil];
第一个是行开头的
NSArray*
声明了一个新的局部变量
images
。这与您试图在
-viewDidUnload
中删除并在
-dealoc
中释放的属性
self.images
不同。从行中删除
NSArray*
将解决此问题,并按照您的意愿将数组存储到
self.images
属性中

这就给了你这样一句话:

images = [[NSArray alloc] initWithObjects: ...strings omitted... ,nil];
第二个问题是,每次使用此方法时都会重新创建
图像
数组。这意味着,即使您解决了第一个问题,您仍然会丢弃旧的数组,而不会在每次通过该方法时释放它,因此您仍然会泄漏这些数组。有多种方法可以解决此问题,但最简单的方法可能是简单地测试您是否已拥有阵列,并仅在尚未创建阵列时创建阵列:

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

(由于该类的所有实例都具有相同的图像名称列表,因此您可以将数组存储在静态变量中,以便在它们之间共享该数组(可能通过调用
dispatch\u一次来初始化)
——但这不太可能有什么区别,除非您同时在屏幕上有此视图控制器的多个实例。)

实际上,这里有两个问题,都围绕着这条线:

NSArray* images = [[NSArray alloc] initWithObjects: ...strings omitted... ,nil];
第一个是行开头的
NSArray*
声明了一个新的局部变量
images
。这与属性
self.images
是分开的,您试图在
-viewDidUnload
中删除它,然后在
-dealloc
中释放它。从行中删除
NSArray*
将解决这个问题,按照您的意愿将数组存储到
self.images
属性中

这就给了你这样一句话:

images = [[NSArray alloc] initWithObjects: ...strings omitted... ,nil];
第二个问题是,每次使用此方法时都会重新创建
图像
数组。这意味着,即使解决了第一个问题,每次使用此方法时都会扔掉旧数组而不释放它,因此仍然会泄漏这些数组d解决这个问题,但最简单的方法可能是简单地测试您是否已经有了一个数组,并且仅在您没有的情况下创建它:

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

(由于该类的所有实例都具有相同的图像名称列表,因此您可以将数组存储在静态变量中,以便在它们之间共享该数组(可能通过调用
dispatch\u一次来初始化)
——但这不太可能有什么区别,除非您同时在屏幕上有此视图控制器的多个实例。)

你真的是手工输入的吗?!你针对的是哪些版本的iOS?自从iOS 6以来,
viewDidUnload
从未被调用,因为视图从未被卸载。它们释放了大部分内部存储(尽管与公共属性无关)但是继续存在,而不是视图控制器完全转储视图。你真的手动键入了吗?!你针对的是哪个版本的iOS?因为iOS 6,
viewDidUnload
从未被调用,因为视图从未被卸载。它们释放了大部分内部存储(尽管与公共属性无关)但是继续存在,而不是视图控制器完全转储视图。是的,这是对的,我认为他有名为images的属性,从未使用过,所以他可以只创建一次,并在不需要时发布。是的,我认为他有名为images的属性,从未使用过,所以他可以在上创建它ce并仅在不需要时释放它。谢谢。那么,我是否像我之前在按钮按下处理程序中设置NSARRay一样全局设置NSARRay,列出所有字符串对象?是的。想法是只执行一次,而不是每次用户按下按钮。因此,我将在viewdidload中在_imageNames或下初始化我的字符串对象我会使用[u image..\u imageNames=[[NSArray alloc]initWithObjects吗