Проблема при использовании многопоточности в программировании iPad (для загрузки большого количества изображений) - PullRequest
1 голос
/ 03 июня 2011

Я должен загрузить большое количество изображений в скроллвью, что, я полагаю, заняло бы некоторое время и память. Итак, я использовал отдельный поток для загрузки этих изображений в фоновом режиме. Я использовал следующий метод многопоточности

[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];
}

}

Ответы [ 2 ]

3 голосов
/ 03 июня 2011

Для каждого основного метода, который вы выполняете в новом потоке, либо через NSThread, либо через performsSelectorInBackground:, вы должны создать пул автоматического выпуска, как этот:

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

   // Do some work.

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

См. Также: Почему нет пула автоматического выпуска, когда я выполняюSelectorInBackground

Но для вашей задачи я предлагаю вам также заглянуть в NSOperationQueue . См., Например, статью Учебное пособие по какао: NSOperation и NSOperationQueue .

1 голос
/ 03 июня 2011

Как сказано в документации :

за метод отвечает aSelector для настройки пула автоматического выпуска недавно отделенная нить и освобождение этот пул, прежде чем он выходит

Итак, в вашем методе prepareSliderView вам нужно создать и выпустить пул авто-релиза:

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

// some work

[pool release];
...