모노크롬에서 iCarousel 라이브러리를 사용하려고합니다. 라이브러리를 성공적으로 포팅했는데 모든 것이 완벽하게 작동하지만 이미지가있는 UIImageViews를 너무 많이 입력하면 응용 프로그램이 충돌합니다. 이는 iCarousel이 UIScrollView와 유사하기 때문에 정상입니다.지연로드 및 멀티 스레딩
필자는 보조 스레드에서 시스템을 느리게로드하고 3-4 개의 이미지 만 한 번에 표시해야하지만이 작업을 원활하게 수행하는 방법을 모르겠습니다. 이때
, I는 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 화상을 표시하는 메인 쓰레드가 다른 모든 이미지를 지우는 다른 스레드는이를 숨 깁니다.
메모리가 정상이지만 기기에서 부드럽 지 않아 스크롤 할 때 '잠시 멈춤'상태가됩니다. 이 작업을 수행하는 또 다른 방법이 있습니까? 아니면 알고리즘을 변경해야합니까?
아마도 bool이 거짓이 될 때까지 기다리는 핫 루프에서 회전하지 않도록 노력해야합니다. 이것은 전체 CPU를 소모합니다! 최소한 Thread.Sleep (10)을 거기에 삽입하십시오. – usr
이 코드는 깨졌습니다. 백그라운드 스레드 (hideInvisibleImages)에서 UIKit 요소에 액세스하고 있으며 이로 인해 임의의 메모리 손상이 발생합니다. –
@ miguel.de.icaza, 당신은 img.Image.Dispose() 전에 invokeOnMainThread를 사용해야한다는 것을 의미합니까? – Daniel