1

私はかなり経験豊富な C プログラマーですが、IOS は私にとって初めてのことです。メモリ リークがあります (これは、MemoryWarning が発生し、すぐにアプリが容赦なく強制終了されるためだと思います)。しかし、インスツルメンツのメモリリーク検出器は、すべて問題ないと言っています。はい、X 秒ごとにメモリ スナップショットを実行しています。一方、VM Tracker を実行すると、メモリの使用量が増えていることがわかります。手がかりと思われる「CG画像」が記憶の大部分を占めています。「if 0」-s を使用してリークが発生している場所を絞り込んだので、次のようになります。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 

    UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
#if 1
    /****** Draw stuff on every frame screen *******/
    CGImageRef imageRef = image.CGImage;

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, image.size.width, image.size.height, 8, image.size.width * 4, colorSpaceRef,kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);    
    CGContextDrawImage(context, CGRectMake(0, image.size.height*-0.1, image.size.width, image.size.height*1.2 ),imageRef);
#endif

#if 0
    if (backgroundJobRunning1 == NO) {
        backgroundJobRunning1 = YES;

        NSValue *value1 = [NSValue valueWithPointer:image];
        // start1 = [NSDate timeIntervalSinceReferenceDate];
        NSArray *array = [NSArray arrayWithObjects:value1, nil];
//        [self performSelectorInBackground:@selector(cleverStuffWithImage:) withObject:array ];
        [self cleverStuffWithImage:(array)];
    }
#endif
    if(sum>0) {
        CGPoint p1= CGPointMake(image.size.height-mycorners[0].y ,image.size.width-mycorners[0].x );
        CGPoint p2= CGPointMake(image.size.height-mycorners[1].y ,image.size.width-mycorners[1].x );
        CGPoint p3= CGPointMake(image.size.height-mycorners[2].y ,image.size.width-mycorners[2].x );
        CGPoint p4= CGPointMake(image.size.height-mycorners[3].y ,image.size.width-mycorners[3].x );
        [_layer setpoints:p1 withArg2:p2 withArg3:p3 withArg4:p4];
    }

    /***** Release everything we allocated */
#if 0
    CGImageRef cgImage = CGBitmapContextCreateImage( context );
 //   imageRef = (CGImageRef)[[(id)imageRef retain] autorelease];

    UIImage *image2 = [[UIImage alloc] initWithCGImage:cgImage];
    if(_settingImage == NO) {
        _settingImage = YES;
        [self performSelectorInBackground:@selector(setImageToView:) withObject:image2];
    } else {
        CCLOG(@"missed frame");
    }

    CGImageRelease(cgImage);
#endif

#if 1
    CGColorSpaceRelease( colorSpaceRef );
    CGContextRelease( context );
#endif
}
#if 0
- ( IplImage * )createGrayIplImage: ( UIImage * )image {
    CGImageRef imageRef  = image.CGImage;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    IplImage * iplImage  = cvCreateImage( cvSize( image.size.width, image.size.height ), IPL_DEPTH_8U, 4 );
    CGContextRef context = CGBitmapContextCreate(iplImage->imageData,
                                          iplImage->width,
                                          iplImage->height,
                                          iplImage->depth,
                                          iplImage->widthStep,
                                          colorSpaceRef,
                                          kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault
                                          );

    CGContextDrawImage( context, CGRectMake(0, 0, image.size.width, image.size.height), imageRef);
    CGContextRelease( context );
    CGColorSpaceRelease( colorSpaceRef );

    IplImage * returnImage = cvCreateImage( cvGetSize( iplImage ), IPL_DEPTH_8U, 1 );
    cvCvtColor( iplImage, returnImage, CV_RGBA2GRAY );
    cvReleaseImage( &iplImage );
    return returnImage;
}
#endif
- (void)dealloc {
    [[CCDirector sharedDirector] end];
    [window release];
    [super dealloc];
}

「#if 1」-s が今のようになるとリークが発生します。私がリリースしていないものは何ですか?

実際、私は同様の問題をもっと抱えていて、UIImage と CGImage の関係について知らないことがあると思います。たとえば、「CGImageRef imageRef = image.CGImage;」かどうかはよくわかりません。何かを割り当て、いつ解放されるか。解放しようとすると、ダブルフリーエラーが発生しました。その間、これらのいずれかをバックグラウンド スレッドに渡し、メモリ リークが発生しました。

4

1 に答える 1

2

うーん、追加するようです

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

初めにそして

[pool release]

問題を解決しました。私はそれがスレッドのようにこれを処理することを知りませんでした。

于 2012-06-25T01:41:57.473 に答える