[英]UIScrollView with UIImageView, UIImage
我在這里或其他谷歌頁面上閱讀了很多帶有UIImageView線程的UIScrollView。 但是我仍然無法解決我面臨的問題。 我現在感冒了。 希望我仍然可以說清楚,大聲笑。 這是問題所在:
我正在構建一個主要使用UIScrollView來顯示一些圖像的應用程序。 這里的數量是計數,而不是大小,通常是100KB(我什至將PNG轉換為jpg,不確定是否有幫助)。 圖像不超過10張,我的應用程序崩潰並顯示內存警告。 這是我第一次遇到內存問題,因為已編譯的應用程序小於10MB,這讓我感到驚訝。
一開始,我會在啟動時加載所有圖像,循環所有圖像文件名稱,然后執行
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imgName]];
[scrollview addSubview:imageView];
[imageView release];
如果我是對的,我認為啟動后所有圖像都在內存中,對嗎? 但有趣的是,該應用程序可以啟動而沒有任何問題(最多為1級內存警告)。 滾動幾張圖像后,它崩潰了。 我檢查泄漏確定,也分配。 在滾動過程中,沒有泄漏和分配幾乎沒有變化。
那么,imageNamed是否有一些特殊的事情要做,而不是緩存?
然后,是的,我轉向了延遲加載。
由於擔心檢查頁面和按需加載圖像可能會導致滾動跳動(事實證明如此),我使用了一個線程,該線程運行一個循環來檢查滾動視圖的偏移量並加載/卸載圖像。
我通過記住圖像名稱對UIImageView進行了子類化。 它還包含將在該線程上執行的loadImage和unloadImage。
- (void)loadImage {
/if ([self.subviews count] == 0) { UIImageView iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:self.imageName]];
[self performSelectorOnMainThread:@selector(renderImage:) withObject:iv waitUntilDone:NO];
//[self addSubview:iv];
[iv release];
}*/
if (self.image == nil) {
//UIImage *img = [UIImage imageNamed:self.imageName];
UIImage *img = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[self.imageName stringByDeletingPathExtension] ofType:[self.imageName pathExtension]]];
// image must be set on main thread as UI rendering is main thread's responsibility
[self performSelectorOnMainThread:@selector(renderImage:) withObject:img waitUntilDone:NO];
[img release];
}
}
// render image on main thread - (void)renderImage:(UIImage*)iv { //[self addSubview:iv]; self.image = iv; }
- (void)unloadImage { self.image = nil; //[(UIView*)[self.subviews lastObject] removeFromSuperview]; }
您可以看到我玩過的帶注釋的代碼。
在unloadImage中,如果我寫[self.image release]
,則得到EXC_BAD_ACCESS,這是意外的,因為我認為alloc和release在這里匹配。
該應用程序仍然崩潰,沒有泄漏。 initWithContentsOfFile
版本甚至比imageNamed版本更早崩潰,並且滾動也不那么順利。
我在設備上運行該應用程序。 通過檢查分配,我發現imageNamed
版本使用的內存比initWithContentsOfFile
版本少得多,盡管它們都崩潰了。 儀器還顯示分配的圖像是2,3或4,這表明延遲加載確實完成了他的工作。
我檢查了WWDC2010的PhotoScroller,但我認為它不能解決我的問題。 不涉及縮放或巨大圖片。
任何人都可以幫助! 先感謝您。
崩潰日志什么也沒說。 該應用程序大部分在內存警告級別= 2后崩潰。如果在模擬器上運行,則不會有問題。
您可以將所有圖像加載到陣列。 您可以設計一個具有一個圖像視圖的視圖,然后嘗試以下代碼:
數組名稱:examplearray和視圖名稱:exampleview
-(void)updateImagesInScrollView
{
int cnt = [examplearray count];
for(int j=0; j< cnt; ++j)
{
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:@"exampleview"
owner:self
options:nil];
UIView *myView = [nibContents objectAtIndex:0];
exampleview * rview= (exampleview *)myView;
/* you can get your iamge from the array and set the image*/
rview.imageview.image = yourimage;
/*adding the view to your scrollview*/
[self.ScrollView addSubview:rview];
}
/* you need to set the content size of the scroll view */
self.ScrollView.contentSize = CGSizeMake(X, self.mHorizontalScrollView.contentSize.height);
}
圖像使用哪種格式都沒有關系。 當您顯示它們時,它們將轉換為位圖。
我建議使用類似於UITableView的技術(隱藏圖像並釋放它從屏幕上消失時使用的內存,並僅在需要顯示它時才實例化該圖像)。
作為一種替代方法-如果您需要在網格中顯示這些圖像-您可以看一下CATiledLayer。
無論如何,將所有圖像加載到內存中並不是最好的主意:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.