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吗