iphone - Problem dealloc'ing memory used by UIImageViews with fairly large image in an UIScrollView -
i have large uiscrollview i'm placing 3-4 rather large (320x1500 pixels or so) uiimageview image tiles. i'm adding these uiimageviews scroll view inside of nib files. have 1 outlet on controller, , uiscrollview. i'm using property (nonatomic, retain) this, , sythesizing it.
my question this: when observe in memory monitor, can see memory used goes quite bit when view these images loaded (as expected). when leave view, , controller dealloc'd, not seem give anywhere near memory had taken up. when cut 1 of these views (there several in app) down 1-3 images 320x460 , left else same, recaptures memory fine.
is there issue using images large? doing wrong in code (pasted below)?
this snippet viewcontroller causing problems.
- (cgfloat)findheight { uiimageview *imageview = nil; nsarray *subviews = [self.scrollview subviews]; cgfloat maxyloc = 0; (imageview in subviews) { if ([imageview iskindofclass:[uiimageview class]]) { cgrect frame = imageview.frame; if ((frame.origin.y + frame.size.height) > maxyloc) { maxyloc = frame.origin.y; maxyloc += frame.size.height; } } } return maxyloc; } - (void)viewdidload { [super viewdidload]; [self.scrollview setcontentsize:cgsizemake(320, [self findheight])]; [self.scrollview setcancancelcontenttouches:no]; self.scrollview.indicatorstyle = uiscrollviewindicatorstylewhite; self.scrollview.clipstobounds = yes; self.scrollview.scrollenabled = yes; self.scrollview.pagingenabled = no; } - (void)dealloc { nslog(@"day controller dealloc'd"); self.scrollview = nil; [super dealloc]; }
update: i've noticed weird phenomenon. if don't use scroll on view, seems hanging on memory. if scroll around bunch , ensure of uiimageviews became visible @ 1 point, free , regain of memory lost.
update2: reason i'm asking app crashing due low memory. wouldn't mind if caching , using memory, doesn't seem ever release - in didreceivemmorywarning conditions
i've solved mystery - , i'm pretty sure bug on apple's side.
as kendall suggested (thanks!), problem lies in how interfacebuilder loads images nib file. when initfromnib, uiimageviews init uiimage using imagenamed: method of uiimage. call uses caching image. normally, want. however, large images , additionally ones scroll far off of visible area, not seem obeying memory warnings , dumping cache. believe bug on apple's side (please comment if agree/disagree - i'd submit if others agree). said above, memory used these images seem released if user scrolls around enough make visible.
the workaround i've found (also kendall's suggestion) leave image name blank in nib file. lay out uiimageview elements normal, don't select image. in viewdidload code, go in , load image using imagewithcontentsoffile: instead. method not cache image, , therefore not cause memory issues retaining large images.
of course, imagenamed: lot easier use, because defaults in bundle, rather having find path. however, can path bundle following:
nsstring *fullpath = [[[nsbundle mainbundle] bundlepath];
putting together, here's looks in code:
nsstring *fullpath = [[[nsbundle mainbundle] bundlepath] stringbyappendingstring:[nsstring stringwithformat:@"/%@-%d.png", self.nibname, imageview.tag]]; uiimage *loadimage = [uiimage imagewithcontentsoffile:fullpath]; imageview.image = loadimage;
so adding code above, full function looks this:
- (cgfloat)findheight { uiimageview *imageview = nil; nsarray *subviews = [self.scrollview subviews]; cgfloat maxyloc = 0; (imageview in subviews) { if ([imageview iskindofclass:[uiimageview class]]) { cgrect frame = imageview.frame; if ((frame.origin.y + frame.size.height) > maxyloc) { maxyloc = frame.origin.y; maxyloc += frame.size.height; } nsstring *fullpath = [[[nsbundle mainbundle] bundlepath] stringbyappendingstring:[nsstring stringwithformat:@"/%@-%d.png", self.nibname, imageview.tag]]; nslog(fullpath); uiimage *loadimage = [uiimage imagewithcontentsoffile:fullpath]; imageview.image = loadimage; } } return maxyloc; }
Comments
Post a Comment