質問

I am working on an iPad application where I have a custom subclass of UIView that contains a UIWebView that displays HTML-formatted text (I named it an EssayView). I have one instance of these UIView subclasses on each page of a UIScrollView. The user scrolls it sideways to choose between the different texts, then scrolls down to read through the text. The scrollview has ten of these EssayViews.

My app should support all orientations, but when the user rotates the device (landscape to portrait or vice versa), memory warnings are thrown, and the app usually crashes.

I did some profiling. On an iPad 3 running iOS 5, the app consumes 528MB of Virtual Memory when displaying the EssayScrollView, but on an iPad 1 running iOS 5 it consumes only 193MB... It still crashes on both. On an iPad 3 running iOS 6, the app consumes 640MB of Virtual Memory when displaying the EssayScrollView, but doesn't crash upon rotation. So the problem seems to be with devices running iOS 5...

Here's how I initialize my EssayView instances:

EssayView.m

@interface EssayView()
@property UIWebView *essayWebView;
@property NSString *essayName;
@property int essayNumber;
@end

@implementation EssayView

- (id)initWithEssayNamed:(NSString *)theEssayName number:(int)theEssayNumber{
    self = [super initWithFrame:CGRectMake(0,0,[[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
    if(self){
        essayNumber = theEssayNumber;
        essayName = theEssayName;

        essayWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
        essayWebView.center = CGPointMake(self.bounds.size.width/2, essayWebView.center.y);
        [essayWebView setScalesPageToFit:NO];
        essayWebView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        essayWebView.delegate = self;
    }
    return self;
}

Here's my rotation code in the EssayViews' parent view:

EssayScrollView.m

- (BOOL)shouldAutorotate{
    return YES;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return YES;
}

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [scrollView setContentSize:CGSizeMake([essayArray count] * scrollView.frame.size.width, scrollView.frame.size.height)];
    [scrollView setContentOffset:CGPointMake(scrollView.bounds.size.width*currentEssay, 0) animated:NO];
}

The line where I assign a set of UIViewAutoresizingMasks to the UIWebView in EssayView seems to be causing the problem. If I comment it out, the UI rotates fine and smoothly (but of course the UIWebView doesn't autoresize).

When testing on iOS 5, it throws a memory warning, rotates after a few seconds and often crashes. On iOS 6 however it doesn't crash. On both OS, the rotation animation is slower than usual and clunky.

Is there a way to make my multiple webviews resize without causing memory warnings and crashes?

役に立ちましたか?

解決

Those memory numbers are far too high. You're basically having 10 browser tabs open and frontmost simultaneously and expecting the OS to re-render them all on rotation. You need to think about re-using the web views rather than having 10 of them in existence at once.

The user can only view one essay at once, presumably, so there is no need to have all of them loaded at the same time. You can cache scroll position or other state and re-apply it when you load the view.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top