令人难以置信的QTMovie出口崩溃

时间:2011-05-11 06:04:14

标签: cocoa video quicktime

嘿,伙计们......我的斗智尽头。在过去的3天里,我一直专注于这个问题,而且我仍然没有接近解决它。我有一个视频队列,我正在后台线程中一个接一个地转换。大部分时间它按预期工作,但每隔一段时间,我就会发生一次奇怪的崩溃,总是在同一点上。我不能为我的生活弄清楚为什么会发生这种情况。我已经启用了垃圾收集。这是我的转换代码。

这是堆栈跟踪。

编辑:经过多一点调试后,我又回到了可能与垃圾收集器相关的结论。如果我将以下行放在转换视频的行之前,我会看到这些错误的数量急剧增加......

[[NSGarbageCollector defaultCollector] collectExhaustively];

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 < 100)
            {
                NSString* nextPath = [conversionPaths objectAtIndex:convertingIndex];

                NSLog(@"ITERATION %d", iterations);
                [self convertVideo:nextPath];

                convertingIndex += 1;
                if(convertingIndex >= [conversionPaths count])
                    convertingIndex = 0;

                iterations += 1;
            }
        }

        - (void) openMovieOnMainThread:(NSString*)path
        {
            NSError* error = nil;
            movie = [[QTMovie alloc] initWithFile:path error:&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:&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;
        }

1 个答案:

答案 0 :(得分:1)

啊......我发现这是一个愚蠢的垃圾收集器。重新设计我的应用程序以使用引用计数而不是垃圾收集和顺利航行。有没有其他人遇到类似的垃圾收集错误?我对我的电影文件的根对象有一个强烈的引用,所以我认为这不是问题所在。