在 iPad 编程中使用多线程时出现问题(用于加载大量图像)

发布于 2024-11-11 18:45:55 字数 3381 浏览 3 评论 0原文

我应该将大量图像加载到滚动视图上,我想这会花费一些时间和内存。因此,我使用了一个单独的线程在后台加载这些图像。我使用了以下多线程方法

[NSThread detachNewThreadSelector:@selector(prepareSliderView) toTarget:self withObject:nil];

在单独的线程上加载图像。在实现此方法时,我在 GDB 中收到以下消息,

NSAutoreleaseNoPool(): Object 0x10647180 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10647300 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10646a00 of class NSCFString autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10647480 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10646a20 of class UIImage autoreleased with no pool in place - just leaking

我不知道这意味着什么,因为我以前从未执行过此方法。所以,我的问题是

1 - 我是否应该使用一些 autoRelease 池以及此方法

2 - 有没有其他方法可以加载大量图像而不需要大量负载主线程

-(IBAction)prepareSliderView{
NSLog(@"Preparing slider view");

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

int totalPages=[kbDataSource numberOfPagesInBook];
sliderScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-300, self.view.frame.size.width,200 )];
sliderScrollView.contentSize = CGSizeMake(totalPages*150+((totalPages-1)*10), 200); 
sliderScrollView.backgroundColor=[[UIColor blackColor] colorWithAlphaComponent:1.0];
thumbnailContentView = [[UIView alloc] initWithFrame:CGRectMake(10, 0, sliderScrollView.contentSize.width, sliderScrollView.contentSize.height)];

newPageSlider.continuous=YES;
newPageSlider.minimumValue=1;
newPageSlider.maximumValue=totalPages;

 thumbnailFrame = CGRectMake(0, 25, 120, 150);
 pageNumFieldFrame = CGRectMake(0, thumbnailFrame.size.height+10, thumbnailFrame.size.width, 50);
for(int i=1;i<totalPages;i++){
    thumbnailView = [[UIView alloc] initWithFrame:thumbnailFrame];
    thumbnailView.backgroundColor=[UIColor clearColor];
    UIButton *thumbnail = [[UIButton alloc] initWithFrame:thumbnailFrame];
    UILabel *pageNumField = [[UILabel alloc] initWithFrame:pageNumFieldFrame];
    pageNumField.backgroundColor=[UIColor clearColor];
    thumbnail.tag=i+1;
    thumbnailView.tag=i+1;

    id<PageDataSource> pd = [kbDataSource pageAtIndex:i];

    thumbnailFrame = CGRectMake(thumbnailFrame.origin.x+150+10, thumbnailFrame.origin.y, 120, 150);
    pageNumFieldFrame = CGRectMake(pageNumFieldFrame.origin.x+150+10, pageNumFieldFrame.origin.y, thumbnailFrame.size.width, 50);
    [thumbnail setBackgroundImage:[pd thumbnailImageForPageNumber:i] forState:UIControlStateNormal];
    pageNumField.text =[NSString stringWithFormat:@"Page %d",i];
    pageNumField.textColor=[UIColor whiteColor];
    [thumbnailContentView addSubview:thumbnailView];
    [sliderScrollView addSubview:pageNumField];
    [sliderScrollView addSubview:thumbnail];
    [sliderScrollView addSubview:thumbnailView];
    [sliderScrollView bringSubviewToFront:thumbnail];
    [sliderScrollView bringSubviewToFront:pageNumField];
    [self.view bringSubviewToFront:thumbnail];
    [thumbnailView release];
    [pageNumField release];
    [thumbnail release];
    [thumbnail addTarget:self action:@selector(navigateToPage:) forControlEvents:UIControlEventTouchUpInside];
    [pool release];
}

}

i am supposed to load large number of images on to a scrollview which, i suppose would take some time and memory. So, i used a separate thread to load these images in the background. I have used the following multi threading method

[NSThread detachNewThreadSelector:@selector(prepareSliderView) toTarget:self withObject:nil];

to load the images on a separate thread. While implementing this method i am getting the following messages in my GDB

NSAutoreleaseNoPool(): Object 0x10647180 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10647300 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10646a00 of class NSCFString autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10647480 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10646a20 of class UIImage autoreleased with no pool in place - just leaking

I had no clue what this meant as i never executed this method before. So, my questions are

1 - should i use some autoRelease pool along with this method

2 - is there any other way in which i can load large number of images with out putting a lot of load the main thread

-(IBAction)prepareSliderView{
NSLog(@"Preparing slider view");

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

int totalPages=[kbDataSource numberOfPagesInBook];
sliderScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-300, self.view.frame.size.width,200 )];
sliderScrollView.contentSize = CGSizeMake(totalPages*150+((totalPages-1)*10), 200); 
sliderScrollView.backgroundColor=[[UIColor blackColor] colorWithAlphaComponent:1.0];
thumbnailContentView = [[UIView alloc] initWithFrame:CGRectMake(10, 0, sliderScrollView.contentSize.width, sliderScrollView.contentSize.height)];

newPageSlider.continuous=YES;
newPageSlider.minimumValue=1;
newPageSlider.maximumValue=totalPages;

 thumbnailFrame = CGRectMake(0, 25, 120, 150);
 pageNumFieldFrame = CGRectMake(0, thumbnailFrame.size.height+10, thumbnailFrame.size.width, 50);
for(int i=1;i<totalPages;i++){
    thumbnailView = [[UIView alloc] initWithFrame:thumbnailFrame];
    thumbnailView.backgroundColor=[UIColor clearColor];
    UIButton *thumbnail = [[UIButton alloc] initWithFrame:thumbnailFrame];
    UILabel *pageNumField = [[UILabel alloc] initWithFrame:pageNumFieldFrame];
    pageNumField.backgroundColor=[UIColor clearColor];
    thumbnail.tag=i+1;
    thumbnailView.tag=i+1;

    id<PageDataSource> pd = [kbDataSource pageAtIndex:i];

    thumbnailFrame = CGRectMake(thumbnailFrame.origin.x+150+10, thumbnailFrame.origin.y, 120, 150);
    pageNumFieldFrame = CGRectMake(pageNumFieldFrame.origin.x+150+10, pageNumFieldFrame.origin.y, thumbnailFrame.size.width, 50);
    [thumbnail setBackgroundImage:[pd thumbnailImageForPageNumber:i] forState:UIControlStateNormal];
    pageNumField.text =[NSString stringWithFormat:@"Page %d",i];
    pageNumField.textColor=[UIColor whiteColor];
    [thumbnailContentView addSubview:thumbnailView];
    [sliderScrollView addSubview:pageNumField];
    [sliderScrollView addSubview:thumbnail];
    [sliderScrollView addSubview:thumbnailView];
    [sliderScrollView bringSubviewToFront:thumbnail];
    [sliderScrollView bringSubviewToFront:pageNumField];
    [self.view bringSubviewToFront:thumbnail];
    [thumbnailView release];
    [pageNumField release];
    [thumbnail release];
    [thumbnail addTarget:self action:@selector(navigateToPage:) forControlEvents:UIControlEventTouchUpInside];
    [pool release];
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不顾 2024-11-18 18:45:55

对于您在新线程中通过 NSThread 或通过 performsSelectorInBackground: 执行的每个 main 方法,您必须创建一个像这样的自动释放池:

- (void)myBackgroundOperation
{
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

   // Do some work.

   // At the very end, release the pool.
   [pool release];
}

另请参阅: ​​为什么没有自动释放池当我执行 PerformSelectorInBackground

但对于您的任务,我建议您还查看 NSOperationQueue.例如,请参阅文章 Cocoa 教程:NSOperation 和 NSOperationQueue

For each main method that you execute in a new thread, either via NSThread or via performsSelectorInBackground:, you have to create an autorelease pool like this:

- (void)myBackgroundOperation
{
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

   // Do some work.

   // At the very end, release the pool.
   [pool release];
}

See also: Why is there no autorelease pool when I do performSelectorInBackground

But for your task I suggest you also look into the NSOperationQueue. See for example the article Cocoa Tutorial: NSOperation and NSOperationQueue.

戏剧牡丹亭 2024-11-18 18:45:55

作为 文档说

aSelector 负责的方法
用于设置自动释放池
新分离的线程并释放
该池在退出之前

因此,在您的 prepareSliderView 方法中,您需要创建并释放一个自动释放池

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// some work

[pool release];

As the documentation says:

the method aSelector is responsible
for setting up an autorelease pool for
the newly detached thread and freeing
that pool before it exits

So, in your prepareSliderView method you need to create and release an autorelease pool:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// some work

[pool release];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文