title: Mind boggling QTMovie export crash
body: <p>Hey guys... I'm at my wits end here. I've been focusing on this issue for the last 3 days it seems, and I'm still no closer to solving it. I've got a queue of videos that I'm converting one after the other in a background thread. Most of the time it works as expected, but every so often, I get a weird crash, always at the same point. I can't for the life of me figure out why it's happening. I've got garbage collection enabled. Here is my conversion code.</p>
  
  <p>Here is the stack trace.</p>
  
  <p><strong>Edit:</strong> After a bit more debugging, I am back to the conclusion that maybe it is garbage collector related. If I place the following line just before the line that converts the video, I get a drastic increase in the amount of these errors that I see...</p>
  
  <p>[[NSGarbageCollector defaultCollector] collectExhaustively];</p>
  
  <pre><code>NSInvalidArgumentException
  
  -[NSPathStore2 objectForKey:]: unrecognized selector sent to instance 0x1073570
  
  (
      0   CoreFoundation                      0x92fc16ba __raiseError + 410
      1   libobjc.A.dylib                     0x901b4509 objc_exception_throw + 56
      2   CoreFoundation                      0x9300e90b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
      3   CoreFoundation                      0x92f67c36 ___forwarding___ + 950
      4   CoreFoundation                      0x92f67802 _CF_forwarding_prep_0 + 50
      5   QTKit                               0x903d3280 MovieProgressProc + 62
      6   QuickTime                           0x95a66062 convertFileProgress + 212
      7   QuickTime3GPP                       0x1e7bcaa2 Spit3GP2_Progress + 180
      8   QuickTime3GPP                       0x1e7c01d8 Spit3GP2_FromProceduresToDataRef + 3438
      9   CarbonCore                          0x90b0d054 _ZL38CallComponentFunctionCommonWithStoragePPcP19ComponentParametersPFlvEm + 54
      10  QuickTime3GPP                       0x1e7be33d Spit3GP2_ComponentDispatch + 129
      11  CarbonCore                          0x90b057c9 CallComponentDispatch + 29
      12  QuickTime                           0x95befb97 MovieExportFromProceduresToDataRef + 49
      13  QuickTime3GPP                       0x1e7bdf84 Spit3GP2_ToDataRef + 1987
      14  CarbonCore                          0x90b1865d callComponentStorage_4444444 + 63
      15  CarbonCore                          0x90b0d054 _ZL38CallComponentFunctionCommonWithStoragePPcP19ComponentParametersPFlvEm + 54
      16  QuickTime3GPP                       0x1e7be33d Spit3GP2_ComponentDispatch + 129
      17  CarbonCore                          0x90b057c9 CallComponentDispatch + 29
      18  QuickTime                           0x95befbe2 MovieExportToDataRef + 73
      19  QuickTime                           0x95a6e9bb ConvertMovieToDataRef_priv + 1690
      20  QuickTime                           0x95bdc591 ConvertMovieToDataRef + 71
      21  QTKit                               0x903e0954 -[QTMovie_QuickTime writeToDataReference:withAttributes:error:] + 2692
      22  QTKit                               0x903c5110 -[QTMovie_QuickTime writeToFile:withAttributes:error:] + 111
      23  Mevee                               0x0005871d -[ConversionQueue convertVideo:] + 509
      24  Mevee                               0x00058341 -[ConversionQueue startConvertingItems] + 145
      25  Foundation                          0x9520fbf0 -[NSThread main] + 45
      26  Foundation                          0x9520fba0 __NSThread__main__ + 1499
      27  libSystem.B.dylib                   0x9475a85d _pthread_start + 345
      28  libSystem.B.dylib                   0x9475a6e2 thread_start + 34
  )
  
  - (id) init
          {
              if(!(self = [super init])) return self;
  
              convertingIndex = 0;
              conversionPaths = [[NSMutableArray alloc] init];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/2 Fast 2 Furious/2 Fast 2 Furious.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/101 Dalmations/101 Dalmations.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/300/300.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/1408/1408.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/A Few Good Men/A Few Good Men.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/A Goofy Movie/A Goofy Movie.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/A Single Man/A Single Man.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/A View to a Kill/A View to a Kill.mp4"];
              [conversionPaths addObject:@"/Users/Morgan/Desktop/Convertable Media/Movies/Across the Universe/Across the Universe.mp4"];
  
              backgroundThread = [[NSThread alloc] initWithTarget:self selector:@selector(startConvertingItems) object:nil];
              [backgroundThread start];
  
              return self;
          }
  
          - (void) startProcessingQueue
          {
  
          }
  
          - (void) startConvertingItems
          {
              NSInteger iterations = 0;
              while(iterations &lt; 100)
              {
                  NSString* nextPath = [conversionPaths objectAtIndex:convertingIndex];
  
                  NSLog(@"ITERATION %d", iterations);
                  [self convertVideo:nextPath];
  
                  convertingIndex += 1;
                  if(convertingIndex &gt;= [conversionPaths count])
                      convertingIndex = 0;
  
                  iterations += 1;
              }
          }
  
          - (void) openMovieOnMainThread:(NSString*)path
          {
              NSError* error = nil;
              movie = [[QTMovie alloc] initWithFile:path error:&amp;error];
  
              if(movie == nil || error != nil || ![movie detachFromCurrentThread])
                  movie = nil;
          }
  
          - (void) closeMovieOnMainThread
          {
              //[movie attachToCurrentThread];
              //[movie release];
          }
  
          - (BOOL) convertVideo: (NSString*)path
          {
              [self performSelectorOnMainThread:@selector(openMovieOnMainThread:) withObject:path waitUntilDone:YES];
  
              if(movie == nil) {
                  NSLog(@"ERROR OPENING MOVIE");
                  return NO;
              }
  
              [QTMovie enterQTKitOnThreadDisablingThreadSafetyProtection];
              [movie attachToCurrentThread];
              [movie setDelegate:self];
  
              NSString* tempItemPath = @"/Users/Morgan/Desktop/test.mp4";
  
              NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
                                     [NSNumber numberWithBool:YES], QTMovieExport,
                                     [NSNumber numberWithLong:'3gpp'], QTMovieExportType,
                                     nil];
  
              NSError* error = nil;
  
              if(![movie writeToFile:tempItemPath withAttributes:attrs error:&amp;error]) {
                  NSLog(@"ERROR CONVERTING MOVIE");
                  return NO;
              }
  
              [movie invalidate];
              [movie detachFromCurrentThread];
  
              [QTMovie exitQTKitOnThread];
              [self performSelectorOnMainThread:@selector(closeMovieOnMainThread) withObject:nil waitUntilDone:YES];
  
              return YES;
          }
  
          - (BOOL)movie:(QTMovie *)aMovie shouldContinueOperation:(NSString *)op withPhase:(QTMovieOperationPhase)phase atPercent:(NSNumber *)percent withAttributes:(NSDictionary *)attributes
          {
              switch (phase) 
              {
                  case QTMovieOperationBeginPhase:
                      NSLog(@"Conversion started");
                      break;
                  case QTMovieOperationUpdatePercentPhase:
                      NSLog(@"Conversion progress: %f", [percent floatValue]);
                      break;
                  case QTMovieOperationEndPhase:
                      NSLog(@"Conversion finished.");
                      break;
              }
  
              return YES;
          }
  </code></pre>