在循环 iphone 中创建多个标签的内存管理
Posted
技术标签:
【中文标题】在循环 iphone 中创建多个标签的内存管理【英文标题】:Memory management with multiple labels created within a loop iphone 【发布时间】:2013-08-11 19:11:38 【问题描述】:我在一个循环中创建多个标签,我对内存管理感到困惑,因为标签的每个实例都具有相同的名称,因为它们都是在循环中创建的,所以这意味着每次在循环,最后分配的标签将被覆盖,不再占用内存,或者它仍然存储在内存中。很困惑,请帮忙,提前谢谢。
- (void)fetchEntrys
JournalrAppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
NSEntityDescription *entityDesc =
[NSEntityDescription entityForName:@"Entrys"
inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request
error:&error];
if ([objects count] == 0)
NSLog(@"No matches");
else
NSLog(@"Matches found");
matches = objects[1];
NSString *firstEntry = [matches valueForKey:@"entry"];
NSLog(@"First Entry: %@", firstEntry);
self.totlal = [objects count];
int i = [objects count] - 1;
NSLog(@"%i", i);
while ( i > -1)
matches = objects[i];
NSString *entry = [matches valueForKey:@"entry"];
NSDate *date = [matches valueForKey:@"date"];
NSDateFormatter *formatDate = [[NSDateFormatter alloc]init];
[formatDate setDateFormat:@"MM/dd/YY"];
NSString *dateString = [formatDate stringFromDate:date];
NSLog(@"Date: %@", dateString);
NSLog(@"Entry: %@", entry);
UILabel *dateLabel = [[UILabel alloc] init];
dateLabel.text = dateString;
dateLabel.frame = CGRectMake(20, cY, 100, 30);
dateLabel.numberOfLines = 3;
dateLabel.font = [UIFont boldSystemFontOfSize:24.0];
[dateLabel setTag:i];
UIButton *deleteButton = [[UIButton alloc]initWithFrame:CGRectMake(230, dateLabel.frame.origin.y, 70, 27)];
[deleteButton addTarget:self action:@selector(deleteButtonPressed) forControlEvents:UIControlEventTouchDown];
[deleteButton setBackgroundImage:[UIImage imageNamed:@"delete.jpg"] forState:UIControlStateNormal];
[deleteButton setTag:i];
cY += 35;
UILabel *labelEntry = [[UILabel alloc]init];
labelEntry.numberOfLines = 0;
labelEntry.text = entry;
CGRect lblFrame = CGRectMake(20, cY, 280, 1000);
labelEntry.frame = lblFrame;
labelEntry.textAlignment = NSTextAlignmentLeft;
labelEntry.backgroundColor = [UIColor clearColor];
[labelEntry sizeToFit];
[labelEntry setTag:i];
UILabel *outerLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, cY - 50, 300, labelEntry.frame.size.height + 80)];
[scrollView addSubview:outerLabel];
outerLabel.layer.borderColor = [UIColor grayColor].CGColor;
outerLabel.layer.borderWidth = 1.0;
outerLabel.tag = i;
if(i ==[objects count] - 1)
self.firstY = outerLabel.frame.origin.y;
//UIImageView *backgroundImage = [[UIImageView alloc]initWithFrame:CGRectMake(10, cY, 312, labelEntry.frame.size.height)];
//backgroundImage.contentMode = UIViewContentModeScaleToFill;
//backgroundImage.image = [UIImage imageNamed:@"post.jpg"];
//NSLog(@"Image Height :%f", backgroundImage.frame.size.height);
//[scrollView addSubview:backgroundImage];
cY += labelEntry.frame.size.height;
NSLog(@"Label Height: %f", labelEntry.frame.size.height);
NSLog(@"currenty: %f", cY);
cY += 100.f;
scrollView.scrollEnabled = YES;
scrollView.showsVerticalScrollIndicator = YES;
[scrollView addSubview: labelEntry];
[scrollView addSubview:dateLabel];
[scrollView addSubview:deleteButton];
NSLog(@"%i", i);
i--;
scrollView.contentSize = CGSizeMake(320, cY);
NSLog(@"cY: %f", cY);
self.currentI = i;
【问题讨论】:
请发布显示问题的代码的最小列表。 您正在将它们添加为滚动视图的子视图,这很好 - 这会增加每个标签的保留计数。您应该在添加到滚动视图后释放每个标签,标签现在将归滚动视图所有,最终会释放它们。见***.com/questions/4163908/… @jarmod 我认为 [view release] 在 ARC 下已被弃用? 是的,我相信你是对的。我更喜欢直言不讳。 【参考方案1】:只要还有一些对标签的引用,它的内存就会被保留。例如,如果您使用[self.view addSubview:label]
,那么标签将与self.view
一样保留在内存中。
同样,如果将标签添加到数组中,标签的内存将被保留,直到数组被释放。
创建具有相同实例名称的新标签后,您将无法再通过它访问旧标签。如果您的标签是视图的子视图,则可以使用[view subviews]
返回子视图数组并使用该数组查找标签。
【讨论】:
但是每个标签都具有相同的实例名称,那么如果第二个标签的实例名称与其他 100 个标签的实例名称相同,我将如何更改它的属性?以及同名的两个类实例如何存在 一旦您创建了一个具有相同实例名称的新标签,您将无法再通过它访问旧标签。如果您的标签是视图的子视图,则可以使用[view subviews]
返回子视图数组并使用该数组查找标签。以上是关于在循环 iphone 中创建多个标签的内存管理的主要内容,如果未能解决你的问题,请参考以下文章
在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)