UITextView在IOS中消耗大量内存

5
这个问题看起来很简单,但是很难找到解决方法。每次在iPhone上使用UITextView时,Xcode中显示的内存使用量都会异常地增加。例如,一个包含短段落(约1KB)的UITextView,在向上和向下滚动时会消耗约17-18MB的内存。更不用说大量文本,如100KB的文件,需要半分钟才能加载到视图中。
以下是我在viewDidLoad()中的实现方式。我不认为这与代码有任何关系,因为当我从storyboard中创建一个带有默认示例文本的新UITextView时,它仍然存在相同的问题。
我有一个NSString读取文件内容,并使UITextView将NSString作为其文本显示。
@interface FileContentViewController ()
@property (weak, nonatomic) IBOutlet UILabel *fileNameTextLabel;
@property (weak, nonatomic) IBOutlet UITextView *fileContentView;
@end

@implementation FileContentViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)displayFileContentInTxtView
{
    if (!self.fileData) {
        self.fileContentView.text=@"file is empty";
        return;
    }

    unsigned char *fileContentBuffer=(unsigned char *)[self.fileData bytes];
    NSString *fileContentString=@"";
    for(int i=0;i<[self.fileData length];i++)
    {
        fileContentString=[fileContentString stringByAppendingString:[NSString stringWithFormat:@"%02x",*(fileContentBuffer+i)]];
    }
    self.fileContentView.text=fileContentString;
    self.fileData=nil;
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    self.fileNameTextLabel.text=self.titleLabelText;
    [self displayFileContentInTxtView];
}

请详细说明“读取文件内容”。 - Aaron
你在Instruments中检查过是UITextView消耗了18MB的内存而不是整个应用程序吗?这是有线内存还是其他什么? - Robotic Cat
问题在于应用程序始终消耗比UITextView中文本大小多1000-2000倍的空间。也就是说,如果在文本视图中有1KB的文本,则应用程序会消耗1-2MB的内存;如果我放置100KB的文本,则内存使用量将增加到200MB。我想除了将文件内容分割成不超过512B的小片段之外,在代码中我无能为力。 - Zhao Chen
2019年,这仍然是一个真实的问题!在此处:https://stackoverflow.com/a/59020919/294884 - Fattie
2个回答

0

尝试仅使用UITextView显示文本而非读取文件内容,这可以通过很少的代码实现:

YourTextViewName.text = @"[put the text to display here]";

或者你可以尝试调整appdelegate.m文件中的voidDidReceiveMemoryWarning部分。

或者,你可以尝试仅显示你正在提取内容的文件,并删除提取内容的代码。


0

这很低效

unsigned char *fileContentBuffer=(unsigned char *)[self.fileData bytes];
NSString *fileContentString=@"";
for(int i=0;i<[self.fileData length];i++)
{
    fileContentString=[fileContentString stringByAppendingString:[NSString stringWithFormat:@"%02x",*(fileContentBuffer+i)]];
}

原因是每次调用 stringByAppendingString 都会分配内存来创建一个新的 NSString 对象。所以如果你的文件大小为2KB,你将创建2048个NSString对象,每个字符串每次都包含一个字符,因此你的程序最终使用n(n+1)/2字节而不释放它(对于2K文件大约是1MB的内存),这还没有考虑NSString内部的内存需求。

尝试像这样做

NSMutableString *fileContentString = [[NSMutableString alloc] initWithCapacity:2*[self.fileData bytes]];
for(int i=0;i<[self.fileData length];i++)
    [fileContentString appendFormat:@"%02x", fileContentBuffer+i];

请注意使用initWithCapacity,这将优化内存分配并避免不必要的重新分配和复制。

是的,这里有一个性能问题,我已经纠正了。但这并不能解决UITextView的内存问题。 - Zhao Chen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接