Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 12-02-2009, 05:00 PM   #1 (permalink)
Tutorial Author
 
Join Date: Feb 2009
Posts: 223
mr tickle is on a distinguished road
Default uiwebview and memory crash (caching and memory useage)

ello fellow iphoners

im in a bit of a bad spot here, for the last week and a half, i have been trying to track down either a slow down in my app, or a crash, recently, in the last few days, i think i have realized what it is

UIWebView

and what a horrible monster it is

im basically pushing views into a uinavigation controller, and the last one to be pushed is a ui webview

UITableView in a uiview > UITableView in a uiview > uiview > UIWebView

the webview is asked to load a url, when you click the last uitablecell in the succession

the problem is seen in the webview as i have tracked it in recieves memory warning.

the uiwebview is being created programatically, and there are no leaks

i have heard that there are issues about uiwebview loading big pages, but crashing when in apps because it has run out of memory, and the delegate recieves a warning

now, my questions are

1. has anyone else seen this
2. is there any way to stop pages caching data, or taking up so much memory
3. is there anything i can do

thanks to those who reply to my problem

much appreciated (iphone app developer at his wits end)
mr tickle is offline   Reply With Quote
Old 12-02-2009, 05:40 PM   #2 (permalink)
Registered Member
 
Join Date: Nov 2009
Posts: 580
ChrisL is on a distinguished road
Default

To clarify, does the memory issue happen within a single UIWebView object, as you're loading multiple pages? Or does the memory increase over time as web views are being created and destroyed, as you push and pop view controllers throughout the lifetime of the app?

It's been a while since I've looked at this, but in a previous app we found that the web view class was internally leaking resources by not cleaning up after itself properly when destroyed. I don't remember all of the details, but I believe that the UIWebView would spawn a new thread the first time HTML was loaded, but the thread was never being stopped (and its memory never freed), even after the web view was destroyed. This wasn't an issue for a single web view, but in situations where web views were created and destroyed frequently, the memory usage would add up and eventually kill the app (although it did take a while). This was on earlier 3.0 OS versions, so I have no idea if things have changed in the newer updates.

Does this sound like the problem you're having? If so, I believe the only workaround we were able to find was to create a static webview object that would persist throughout the lifetime of the app, instead of creating and destroying web view objects as its view controller was pushed and popped. This seemed to prevent the issue described above. We never noticed any other issues, though, so if this isn't the problem you're experiencing then nothing else comes to mind.
ChrisL is offline   Reply With Quote
Old 12-03-2009, 04:25 AM   #3 (permalink)
Tutorial Author
 
Join Date: Feb 2009
Posts: 223
mr tickle is on a distinguished road
Default

this sounds quite right, i will try and place a static webview inside the nib file, and just iboutlet it instead of creating it programatically

webview has turned out to be a horrible monster, you cant even set the cache to not store anything on the phone, correct me if i am wrong

thanks chris, you have given me an extra option here.

i will let you know what happens
mr tickle is offline   Reply With Quote
Old 12-03-2009, 06:31 AM   #4 (permalink)
Tutorial Author
 
Join Date: Feb 2009
Posts: 223
mr tickle is on a distinguished road
Default

chris

when you say you create a webview throughout the whole existence of the app, you mean that you init a UIWebview in your root controller, and whatever view needs, calls the webview into its view, when the view is popped from a navigation stack, you just remove the webview, ready for later use, off course you set its delegate to nil and stop it loading before removing it.

my way, that i have changed to, i just have the webview in the single nib that i need to push into the stack, will this avoid the leak, or will it mean that each time i init the nib, i generate another thread.

thanks
mr tickle is offline   Reply With Quote
Old 12-03-2009, 08:01 AM   #5 (permalink)
Registered Member
 
Join Date: Nov 2009
Posts: 580
ChrisL is on a distinguished road
Default

Quote:
Originally Posted by mr tickle View Post
chris

when you say you create a webview throughout the whole existence of the app, you mean that you init a UIWebview in your root controller, and whatever view needs, calls the webview into its view, when the view is popped from a navigation stack, you just remove the webview, ready for later use, off course you set its delegate to nil and stop it loading before removing it.

my way, that i have changed to, i just have the webview in the single nib that i need to push into the stack, will this avoid the leak, or will it mean that each time i init the nib, i generate another thread.

thanks
I believe that each time you initialize the nib file, a new web view is created. Maybe I'm misunderstanding what you mean, but if the web view is in the nib for the view controller that is being pushed and popped, then yes, it will still be created and destroyed, and I don't think that will fix the problem. You could put it in the nib for the root view, and it should be OK as long as the root view is never destroyed (although it will still be released and then recreated in the case of a memory warning, but this should hopefully be rare). In this case, you'd have to pass the web view to each view controller that needed it, as you said in your last post.

When I said we created a static web view, I meant it literally; the quick fix was just to make a static variable in the view controller class that contained the web view, and make sure it was initialized only once. Something like:
Code:
@implementation WebViewController

static UIWebView _webView = nil;

...

- (void) viewDidLoad {
   ...

   if (!_webView) {
      _webView = [[UIWebView alloc] initWithFrame:webFrame];
   }

   ...

   [self.view addSubview:_webView];
}

...
The webView is never released, so its retainCount never hits zero, even after the view controller it's been added to has been destroyed. We only ever needed to access the web view from inside WebViewController, so using the static variable wasn't an issue for us.

I should add: regardless of how it's implemented, of course the real test is to watch object allocations/memory usage in instruments as you push and pop the view controllers containing web views. If you can do this for a while without any significant increases in memory, then you should be good.
ChrisL is offline   Reply With Quote
Old 12-03-2009, 10:42 AM   #6 (permalink)
Tutorial Author
 
Join Date: Feb 2009
Posts: 223
mr tickle is on a distinguished road
Default

now i understand

basically, the way i am doing, the nib allocation still messes it up as it keeps being recreated, and therefore the webview reinitializes because i dealloc that specific view and its controller

now, here is the complicated part

1. the controller the navigation controller does get deallocated
2. the web controller is used inside the navigation controller
3. my structure is based like the following

mainController
>>childController
>>>>navigationcontroller
>>>>>>webcontroller
>>childcontroller
>>>>anothercontroller
.... and so on

so, i need to create the webview inside the mainController, because, it is never deallocated, they are all linked through a parent child relationship using assign properties, so i dont mind passing the request down the line to whomever needs it. Its complicated. I was required to create section sub section / sub sub sub section based navigation but it could not use the semantics of uinavigationcontroller. It all works super fine, except for this one problem.

urggg, annoying
mr tickle is offline   Reply With Quote
Old 12-03-2009, 12:42 PM   #7 (permalink)
Registered Member
 
Join Date: Nov 2009
Posts: 580
ChrisL is on a distinguished road
Default

Sounds like you have a handle on this now. Make sure you confirm that you fixed the problem in instruments. Also, if you have a small code sample or can easily make one that confirms the problem, it might be a good idea to submit a bug report to apple. The more people who report this, the faster it's likely to be fixed in a future update.
ChrisL is offline   Reply With Quote
Old 12-03-2009, 03:42 PM   #8 (permalink)
Tutorial Author
 
Join Date: Feb 2009
Posts: 223
mr tickle is on a distinguished road
Default

Quote:
Originally Posted by ChrisL View Post
Sounds like you have a handle on this now. Make sure you confirm that you fixed the problem in instruments. Also, if you have a small code sample or can easily make one that confirms the problem, it might be a good idea to submit a bug report to apple. The more people who report this, the faster it's likely to be fixed in a future update.

chris, you definately helped me out here, thanks a lot.

i also noticed that you should load an empty string into the webview if the viewcontrollers in the stack are 1 after the other

somecontroller // anothercontroller // controllerwithwebview // lastcontrollerwithwebview

now, if i go to controllerwithwebview, and then go to lastcontrollerwithwebview, i basically steal the webview from the previous viewcontroller, so i have to dump an empty string in there before calling the NSURLRequest for a website, and also when popping the stack back to the previous controller, i have to re insert the webview as it was stolen from it by the last controller

pheeewwww, hope that made sense.

anyways, you have been a great help man.

i will continue with testing in app and instruments to see if the problem is fixed, but it looks like it is.

mr tickle
mr tickle is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 332
13 members and 319 guests
akacaj, alexP, ClerurcifeDer, Duncan C, givensur, GraffitiCircus, guusleijsten, JmayLive, NetGuru, Paul Slocum, Punkjumper, Sloshmonster, yys
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,649
Threads: 94,114
Posts: 402,883
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Anwerbl
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 09:46 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0