我正在使用的應用程序相對簡單,但它引發了內存警告。我試圖弄清楚應用程序設計是否需要太多內存,應該重新分配和分解以減少使用,或者應用程序設計沒問題,但是應用程序本身臃腫,不正確地吞噬了超過所需內存的內存。iPad內存限制
該應用程序從Web下載包含一組問題的XML文件,然後生成顯示問題控件列表的UIScrollView。每個問題控件都有一個UITextView和一個UISegmentedControl,UIButton,UITableView,UITextField或四個帶有UIButton(自定義日期控件)的UITextFields。下面是截圖:
這種設置的偉大工程,對於較小的問題集,但應用程序開始投擲內存警告較大的套120的問題。這裏是一個更大的集劃分和VM跟蹤儀器的典型運行:
對XML下載和型號的負載,但警告不拋出,直到分配的內存已經趨於穩定後,分配的內存峯值。虛擬機跟蹤器內存在被拋出時仍然在增加,這讓我認爲控件仍然被加載到內存中,並且虛擬機跟蹤器是導致警告的內存增長的更好指標。當Resident Size大於125 MB時,警告通常會發生。 我發現了一種方法來相當大地降低居民身材。問題控件具有自定義視圖,以使它們具有圓角邊緣和投影。如果我從自定義視圖中註釋掉drawRect代碼(如下所示),則分配內存保持不變,但常駐大小下降大約30 MB,並且不會增長到93 MB以上。我可以找到問題的輕鬆背景,但如果我可以減少內存佔用,我寧願保留圓角邊緣並投下陰影。
- (void)drawRect:(CGRect)rect {
// get the contect
CGContextRef context = UIGraphicsGetCurrentContext();
//for the shadow, save the state then draw the shadow
CGContextSaveGState(context);
CGContextSetShadow(context, CGSizeMake(4,-5), 10);
//now draw the rounded rectangle
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
if(_HighlightColor==nil){
_HighlightColor = [[UIColor whiteColor] retain];
}
CGContextSetFillColorWithColor(context, _HighlightColor.CGColor);
//since I need room in my rect for the shadow, make the rounded rectangle a little smaller than frame
CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect)-30, CGRectGetHeight(rect)-30);
CGFloat radius = 5;
// the rest is pretty much copied from Apples example
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
// Start at 1
CGContextMoveToPoint(context, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
//for the shadow
CGContextRestoreGState(context);
}
儀器和內存警告使它看起來像內存刷爆了,但這些數字似乎很高我。我不認爲在scrollview中這些問題控件中的120個會成爲iPad處理的問題,但我沒有一個關於他們應該使用多少內存的參考框架。考慮到一些iPad可以運行的圖形密集型遊戲,似乎上面的簡單drawRect代碼在問題控件中會佔用超過30 MB的空間。這種內存使用量看起來很高,或者這是您對這個許多簡單的UI元素的應用程序所期望的嗎? drawRect中是否有東西會消耗大量的內存或關於如何優化它的任何建議?如果看起來這樣會使iPad的內存最大化,我會創建標籤或頁面,並限制我放到標籤頁上的問題數量,這樣一次只能將一小部分控件加載到內存中。不過,如果iPad應該能夠在內存中處理它們,我寧可不打破它們。任何輸入是不勝感激。
所以你認爲我說的視圖的數量可能會真實地用盡這麼多的內存?我已經考慮過你提出的觀點,但是認爲它會持續不斷地弄清哪些視圖需要加載和卸載會很慢並且過於複雜。偉大的想法在UITableView!這將處理第二個問題。希望視圖生成足夠輕以便跟上滾動。我會給它一個鏡頭,讓你知道。謝謝! – Wes 2012-02-07 07:50:04
@Wes Views佔用了相當多的內存;我相信每個人都擁有合成所有像素的緩衝區。如果您的視圖生成速度非常慢,您可以爲每種類型的行賦予自己的標識符(使用initWithStyle:Identifier:和deque ... WithIdentifier :)。這樣,你只需要幾次生成每種類型,剩下的時間只需填寫數據。我從來沒有嘗試嵌套的tableviews,但我不明白爲什麼它不應該工作。 – cobbal 2012-02-07 07:54:54