我有一个应用程序可以将多个缩略图加载到UIScrollVIew中。这是一个冗长的操作,为了不阻止UI的其余部分的显示,我在一个单独的线程中运行它。这在第一次启动应用程序时工作正常,但稍后需要将一组新图像加载到UIScrollView中。当我第二次分离线程时,应用程序崩溃(有时)。代码如下:
// this call is in a separate method
[NSThread detachNewThreadSelector:@selector(addThumbnailsToScrollView) toTarget:self withObject:nil];
// this is the main entry point for the thread
- (void) addThumbnailsToScrollView {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool
// now place all the thumb views as subviews of the scroll view
float xPosition = THUMB_H_PADDING;
int pageIndex = 0;
for (Page *page in self.pages) {
// get the page's bitmap image and scale it to thumbnail size
NSString *name = [page valueForKey:@"pageBackground"];
NSString *basePath = [[NSBundle mainBundle] pathForResource:page.pageBackground ofType:@"jpg" inDirectory:nil];
UIImage *thumbImage = [UIImage imageWithContentsOfFile:basePath];
thumbImage = [thumbImage imageScaledToSize:CGSizeMake(80, 100)];
// create a ThumbImageView for each page and add it to the thumbnailScrollView
if (thumbImage) {
ThumbImageView *thumbView = [[ThumbImageView alloc] initWithImage:thumbImage];
[thumbView setDelegate:self];
[thumbView setImageName:name];
[thumbView setImageSize:CGSizeMake(80, 100)];
[thumbView setPageIndex:pageIndex];
pageIndex ++;
CGRect frame = [thumbView frame];
frame.origin.y = 0;
frame.origin.x = xPosition;
[thumbView setFrame:frame];
[thumbnailPagesScrollView addSubview:thumbView];
[thumbView release];
xPosition += (frame.size.width + THUMB_H_PADDING);
}
}
[self hightlightThumbnailPageAtIndex:0];
[(UIActivityIndicatorView *)[thumbnailPagesScrollView.superview viewWithTag:100] stopAnimating];
[pool release]; // Release the objects in the pool.
}
我认为主进入例程完成后,分离的线程就会退出。第二次调用分离线程不是新线程吗?为什么应用程序崩溃,但有时不会?
由于
JK
答案 0 :(得分:2)
您无法在辅助线程中触摸UIKit
(意思是UIScrollVIew
) - 您需要重新组织,以便在辅助线程中进行提取,但您创建一个NSData对象(包含图像二进制)可用于每个缩略图的主线程,以便它可以执行与实际显示它们相关的所有操作。
Apple在文档中反复警告UIKit不是线程安全的。
答案 1 :(得分:0)
我建议将thumbView添加到主线程上的thumbnailPagesScrollView而不是单独的线程。跨线程的对象保留计数可能存在问题。有一个方便的方法performSelectorOnMainThread我认为它是这样做的。您可以将thumbView传递给它,然后将其添加到子视图中。
或者你可以在主线程上执行整个if语句,因为那不会中断用户。
还有你的活动指示器,这应该在主线程上停止。 UI相关的所有内容都应该在主线程上完成。