我試圖在monoouch中使用iCarousel庫。我成功地移植了這個庫,一切都很完美,但是如果你在內部輸入了過多的UIImageViews和圖像,應用程序會崩潰,這是正常的,因爲iCarousel就像UIScrollView一樣。延遲加載和多線程
我絕對必須從輔助線程以某種方式使用延遲加載系統,並且一次只顯示3-4張圖像,但我不知道如何使此工作順利進行。
在這一點上,我設置的iCarousel代表:
bool threadsAlive = true;
public cDelegate()
{
ThreadPool.QueueUserWorkItem(delegate { refresh_visible(); });
}
public override void DidScroll (iCarousel carousel)
{
scrolling = true;
}
public override void DidEndScrollingAnimation (iCarousel carousel)
{
scrolling = false;
//show images that are currently on the screen
ThreadPool.QueueUserWorkItem(delegate { ShowCurrent(); });
//hides images that are not on the screen
ThreadPool.QueueUserWorkItem(delegate { hideInvisibleImages(); });
}
void refresh_visible()
{
while(threadsAlive)
{
while(scrolling)
{
ShowCurrent();
}
}
}
void refresh_hidden()
{
while(threadsAlive)
{
while(scrolling)
{
hideInvisibleImages();
}
}
}
public void ShowCurrent()
{
var ds = _carousel.DataSource as cDataSource;
var left_index = _carousel.CurrentItemIndex - 1;
var right_index = _carousel.CurrentItemIndex + 2;
if(left_index < 0) left_index = 0;
if(right_index >= ds.Lista.Count) right_index = ds.Lista.Count - 1;
//
for(var i = left_index; i < right_index ; i++)
{
var img = ds.Lista[i];
if(img.Image == null)
{
BeginInvokeOnMainThread(delegate{
img.Image = UIImage.FromFile(img.UserObject.ToString());
});
}
}
}
void hideInvisibleImages()
{
Console.WriteLine("ascund!");
var ds = _carousel.DataSource as cDataSource;
var left_index = _carousel.CurrentItemIndex - 1;
var right_index = _carousel.CurrentItemIndex + 2;
if(left_index < 0) left_index = 0;
if(right_index >= ds.Lista.Count) right_index = ds.Lista.Count - 1;
//
for(var i=0; i<left_index; i++)
{
var img = ds.Lista[i];
if(img.Image != null)
{
img.Image.Dispose();
img.Image = null;
}
}
for(var i=right_index; i<ds.Lista.Count; i++)
{
var img = ds.Lista[i];
if(img.Image != null)
{
img.Image.Dispose();
img.Image = null;
}
}
}
的代碼其實很簡單:有一個主線程只顯示當前指數和兩個圖像的左1個圖像提前,另一個線程清理所有其他圖像,隱藏它們。
它的工作,記憶是好的,但它不是在設備上的光滑,它在我滾動時「掛起」一點。還有另一種方法來做到這一點?或者,也許我應該改變算法?
也許你應該儘量不要在熱循環中旋轉等待布爾變成假。這消耗整個CPU!至少插入一個Thread.Sleep(10)。 – usr 2012-01-31 20:42:56
此代碼已損壞。您正在從後臺線程(hideInvisibleImages)訪問UIKit元素,這將導致隨機內存損壞。 – 2012-02-01 15:53:47
@ miguel.de.icaza,你是說我必須在img.Image.Dispose()之前使用invokeOnMainThread? – Daniel 2012-02-01 18:40:53