gpt4 book ai didi

ios - 由于巨大的 UILabel,应用程序内存不足

转载 作者:行者123 更新时间:2023-11-29 02:30:48 27 4
gpt4 key购买 nike

我必须在我的应用程序中显示一个巨大的文本文件。UITextView 不符合我的要求,因为它强制换行,所以我不得不使用 UILabel。由于无法渲染非常大的标签,因此我在 UIScrollView 内使用多个 UILabels 来使其工作。

模拟器上一切正常,但 UILabels 所需的内存约为 300MB。当我在 iPad 2 上运行它时,它会出现内存不足并且应用程序崩溃的情况。

问题是我没有收到任何内存警告。我想在 didReceiveMemoryWarning 中关闭 View Controller ,但它没有被调用,应用程序崩溃而没有任何警告。

我错过了什么?

最佳答案

下面是一个使用 UITableView 来解决您的问题的示例。

HSViewController.h

@interface HSViewController : UITableViewController

@end

HSViewController.m

#import "HSViewController.h"

//#define USE_LABEL

static NSString *const kCellIdentifier = @"kCellIdentifier";

@interface HSViewController ()

@property (atomic, strong) NSArray *linesOfText;
@property (nonatomic, strong) UIFont *font;
@property (nonatomic, assign) NSLineBreakMode lineBreakMode;

- (CGSize)sizeForString:(NSString *)text;

@end

@implementation HSViewController

- (void)viewDidLoad
{
[super viewDidLoad];

self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

self.font = [UIFont systemFontOfSize:14.0f];
self.lineBreakMode = NSLineBreakByWordWrapping;

[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:kCellIdentifier];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *draculaData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Dracula" withExtension:@"txt"]];
NSString *text = [[NSString alloc] initWithData:draculaData encoding:NSASCIIStringEncoding];
#ifndef USE_LABEL
self.linesOfText = [text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
#endif
dispatch_async(dispatch_get_main_queue(), ^{
#ifdef USE_LABEL
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
self.view.bounds.size.width, self.view.bounds.size.height)];
label.font = self.font;
label.lineBreakMode = self.lineBreakMode;
label.numberOfLines = 0;
label.text = text;
[self.view addSubview:label];
#else
NSLog(@"Starting reloading %lu rows", (unsigned long)[self.linesOfText count]);
[self.tableView reloadData];
NSLog(@"Reload finished");
#endif
});
});
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#ifdef USE_LABEL
return 0;
#else
return [self.linesOfText count];
#endif
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
@autoreleasepool {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier forIndexPath:indexPath];
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = self.font;
cell.textLabel.lineBreakMode = self.lineBreakMode;
cell.textLabel.text = self.linesOfText[indexPath.row];
cell.userInteractionEnabled = NO;
return cell;
}
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
@autoreleasepool {
NSString *text = self.linesOfText[indexPath.row];
// Don't let the line height be 0
if ([text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0)
{
text = @"A";
}
return ceil([self sizeForString:text].height);
}
}

#pragma mark - Private

- (CGSize)sizeForString:(NSString *)text
{
@autoreleasepool {
if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])
{
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.lineBreakMode = self.lineBreakMode;
return [text boundingRectWithSize:CGSizeMake(self.tableView.bounds.size.width, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName : self.font,
NSParagraphStyleAttributeName : [style copy]}
context:[NSStringDrawingContext new]].size;
}
else
{
return [text sizeWithFont:self.font
constrainedToSize:CGSizeMake(self.tableView.bounds.size.width, CGFLOAT_MAX)
lineBreakMode:self.lineBreakMode];
}
}
}

@end

你会发现在内存使用上其实并没有太大的区别。 UITableView 版本只节省了大约。内存 10%。

但是,这是动态加载表格 View 单元格的起点。因此,当用户向下滚动(假设屏幕的 90%)时,可以通过更改 tableView:numberOfRowsInSection: 的返回值来加载下一个 X 单元格。

祝你好运。

关于ios - 由于巨大的 UILabel,应用程序内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26907578/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com