1
- (void)imagePickerController:(UIImagePickerController *)picker 
        didFinishPickingImage:(UIImage *)image 
                  editingInfo:(NSDictionary *)editingInfo {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [self.pickerTrigger setImage:image];
    [self.button setTitle:@" " forState:UIControlStateNormal];
    [self.button setTitle:@" " forState:UIControlStateSelected];
    [self.button setTitle:@" " forState:UIControlStateHighlighted];

    CGSize oldSize = [image size];
    CGFloat width = oldSize.width;
    CGFloat height = oldSize.height;
    CGSize targetSize = CGSizeMake(320.0, 400.0);
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

    if (CGSizeEqualToSize(oldSize, targetSize) == NO)
    {
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor > heightFactor)
            scaleFactor = widthFactor;
        else
            scaleFactor = heightFactor;
        scaledWidth = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        if (widthFactor > heightFactor)
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        else if (widthFactor < heightFactor)
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
    }

    UIGraphicsBeginImageContext(targetSize);

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    [image drawInRect:thumbnailRect];

    self.selectedImage = UIGraphicsGetImageFromCurrentImageContext();

    NSLog([NSString stringWithFormat:@"After getting from DB %d", [selectedImage retainCount]]);
    UIGraphicsEndImageContext();
    [pool release];
    [picker dismissModalViewControllerAnimated:YES];
}

変数selectedImageは、インターフェイスファイルで保持されたプロパティとして宣言されています。ご想像のとおり、画像をサムネイルしてselectedImageに保存します。次に、それを別の関数で再利用し、dealloc関数で解放します。

Instrumentsは、オブジェクトの割り当てが解除されても、メモリが増え続けることを示していますか?オブジェクトを解放しても、必ずしもメモリが解放されるとは限らないということですか?

私はUIImagesでこのようなことを頻繁に直面しますか?何か推測はありますか?

[selectedImage release]を(void)dealloc関数に追加しました。この関数は呼び出され、保持カウントがゼロになり、オブジェクトの割り当てが解除されます。ただし、解放されないメモリが割り当てられます(UIGraphicsGetImageFromCurrentImageContext();を使用していると思います)。4〜5枚の画像を追加すると、メモリはシミュレータでなんと117 MBに達し、その後、シミュレータでは48MBに戻ります。しかし、アプリはiPhoneでクラッシュします。イメージを作成するときに他のアプローチを取る必要がありますか?

4

2 に答える 2

0

「保持されたプロパティ」として宣言されたselectedImageがある場合は、それを解放するためにメッセージを送信する必要があります。

これは、画像が setter の暗黙的な呼び出し ( self.selectedImage = XXX ) 内に保持されているためです。これは、コンパイラがプロパティ セッター用に作成するコード内にあるため、表示されません。

于 2009-04-24T14:54:43.157 に答える
0

Instruments は、オブジェクトの割り当てが解除されていることを示していますが、メモリは増加し続けていますか? オブジェクトを解放してもメモリが解放されるとは限らないということですか?

オブジェクトを解放すると、その参照カウンターが 1 減ります。カウンターが 0 になったときにのみメモリから解放されます。

他の何かがそれを使用している場合、UIImage は解放されません。これは、コードまたは Interface builder で作成したビューである可能性があります。

あなたが呼び出している可能性があります メイン回が多すぎるため、参照カウンターがゼロに達することはありません。

また、iPhone のすべてのイベント ループの開始時に、自動解放プールが作成されることに注意してください。いつでもオブジェクトを追加して、自動的にクリーンアップすることができます。

于 2009-04-24T14:54:50.957 に答える