使用大图像块线程在UIScrollview中添加UIImageView

时间:2010-11-25 15:40:31

标签: objective-c multithreading image uiscrollview

我正在UIImageView中加载一个图像,然后我将其添加到UIScrollView中。 图像是局部图像,高度约为5000像素。

问题在于,当我将UIImageView添加到UIScrollView时,线程被阻止。 很明显,因为当我这样做时,我无法滚动UIScrollView直到显示图像。

这是一个例子。

UIScrollView *myscrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 768, 1004)];
myscrollview.contentSize = CGSizeMake(7680, 1004);
myscrollview.pagingEnabled = TRUE;

[self.view addSubview:myscrollview];

NSString* str = [[NSBundle mainBundle] pathForResource:@"APPS.jpg" ofType:nil inDirectory:@""];
NSData *imageData = [NSData dataWithContentsOfFile:str];
UIImageView *singleImageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:imageData]];

    //the line below is the blocking line
[scrollView addSubview:singleImageView];

这是脚本中阻止滚动条的最后一行。当我把它放在外面时,一切都很完美,除了图像当然没有显示的事实。

我似乎记得使用多线程在UIView操作上不起作用,所以我猜这不是问题。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

如果您要提供这些大图片,您应该查看CATiledLayer;有一个关于如何在WWDC 2010中使用它的好视频的视频。

如果这些不是您的图像,并且您无法对其进行缩减采样或将其分解为切片,则可以在背景线程上绘制图像。您可能无法在任何主线程上绘制屏幕图形上下文,但主线程,但这不会阻止您绘制到非屏幕图形上下文。在你的后台主题上你可以

  • 使用CGBitmapContextCreate
  • 创建绘图上下文
  • 将图像绘制在其上,就像在drawRect:
  • 中绘制到屏幕上一样
  • 当您完成加载并绘制图像时,使用performSelectorOnMainThread:withObject:waitUntilDone:
  • 在主线程上调用视图的drawRect:方法

在视图的drawRect:方法中,一旦在内存上下文中完全绘制了图像,请使用CGBitmapContextCreateImage和CGContextDrawImage将其复制到屏幕上。

这不是一件容易的事,您需要在合适的时间启动后台线程,同步访问您的图像等。如果您能找到一种操作图像的方法,CATiledLayer方法几乎肯定是更好的方法使这项工作。

答案 1 :(得分:0)

为什么要一次将如此巨大的图像加载到内存中?将其分成许多小图像并动态加载/释放它。

答案 2 :(得分:0)

尝试在没有UIImage的情况下分配UIImageView,并将其作为子视图添加到UIScrollView。

将UIImage加载到一个单独的线程中,并在另一个线程上运行该方法,以便在将图像加载到内存时设置UIImageView的image属性。你也可能会遇到一些内存问题,因为加载到UIImage中的这个大小的图像可能会是30MB +

UIScrollView *myscrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 768, 1004)];
myscrollview.contentSize = CGSizeMake(7680, 1004);
myscrollview.pagingEnabled = TRUE;

[self.view addSubview:myscrollview];

NSString* str = [[NSBundle mainBundle] pathForResource:@"APPS.jpg" ofType:nil inDirectory:@""];
UIImageView *singleImageView = [[UIImageView alloc] init];

[scrollView addSubview:singleImageView];

//Then fire off a method on another thread to load the UIImage and set the image
//property of the UIImageView.

只要留意内存并注意使用带有UIImage的便利构造函数(或任何可能最终变大的对象)

您目前在哪里运行此代码?