iOS detachNewThreadSelector leaking

2.1k views Asked by At

I have a UIScrollView that I am loading some images in. Sometimes I am apply an effect to an image and it takes a bit to do the pre-loading so I decided to do this on a different thread using detachNewThreadSelector. I am using the KTPhotoBrowser that is on gitHub for this.

So basically, I have a function as so.

- (void)setCurrentIndex:(NSNumber *)newIndex
{

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

   currentIndex_ = [newIndex integerValue];

   [self loadPhoto:currentIndex_];
   [self loadPhoto:currentIndex_ + 1];
   [self loadPhoto:currentIndex_ - 1];
   [self unloadPhoto:currentIndex_ + 2];
   [self unloadPhoto:currentIndex_ - 2];

  [self setTitleWithCurrentPhotoIndex];
  [self toggleNavButtons];
  [pool release];

}

I call this using

[NSThread detachNewThreadSelector:@selector(setCurrentIndex:) toTarget:self withObject:[NSNumber numberWithInt:5]];

When I run this, it appears to be throwing a leak. I am beginning to wonder if I should be putting the AutoRelease pool around the code in the loadPhoto method. If you are curious about this code, I have included it below.

- (void)loadPhoto:(NSInteger)index
{
   if (index < 0 || index >= photoCount_) {
      return;
   }

   id currentPhotoView = [photoViews_ objectAtIndex:index];
   if (NO == [currentPhotoView isKindOfClass:[KTPhotoView class]]) {
      // Load the photo view.
      CGRect frame = [self frameForPageAtIndex:index];
      KTPhotoView *photoView = [[KTPhotoView alloc] initWithFrame:frame];
      [photoView setScroller:self];
      [photoView setIndex:index];
      [photoView setBackgroundColor:[UIColor clearColor]];

      // Set the photo image.
      if (dataSource_) {
         if ([dataSource_ respondsToSelector:@selector(imageAtIndex:photoView:)] ==    NO) {
            UIImage *image = [dataSource_ imageAtIndex:index];
            [photoView setImage:image];
         } else {
        [dataSource_ imageAtIndex:index photoView:photoView];
         }
      }

      [scrollView_ addSubview:photoView];
      [photoViews_ replaceObjectAtIndex:index withObject:photoView];
      [photoView release];
   } else {
      // Turn off zooming.
      [currentPhotoView turnOffZoom];
   }
}

Any ideas would be greatly appreciated.

2

There are 2 answers

3
Kazuki Sakamoto On BEST ANSWER

Your code seems ok but you are using UIKit from another thread. UIKit classes should be used only from an application’s main thread.

UIKit Framework Reference Introduction

0
james lobo On

Use the following

[self performSelectorInBackground:@selector(setCurrentIndex:) withObject:[NSNumber numberWithInt:5]];

instead of

[NSThread detachNewThreadSelector:@selector(setCurrentIndex:) toTarget:self withObject:[NSNumber numberWithInt:5]];

and it eliminates the memory leak.