2

CIFilters を使用して UIImageView の画像に影響を与えるいくつかのスライダーを使用して、色相と明るさを編集するオプションをユーザーに提供しようとしています。

かなりうまく機能していますが、1 つの問題があります。スライダーを使いすぎると、メモリの警告が表示され始め、ユーザーがその後試行を続けると、アプリは終了しますが、クラッシュ ログはありません。 (???これに非常に混乱しています)。

私はまだプログラミングの初心者であり、特にメモリ管理の初心者ですが、ここの誰かが助けてくれることを願っています.

これが私のコードです:

私の .h ファイルで:

@property (weak, nonatomic) IBOutlet UISlider *hueSlider;
@property (weak, nonatomic) IBOutlet UISlider *brightnessSlider;

@property (weak, nonatomic) CIImage *outputImage;
@property (strong, nonatomic) CIFilter *hueFilter;
@property (strong, nonatomic) CIFilter *brightnessFilter;
@property (strong, nonatomic) CIContext *ccontext;
@property (strong, nonatomic) CIImage *inputImage;

- (IBAction)hueValueChangedAction:(id)sender;
- (IBAction)brightnessValueChangedAction:(id)sender;

また、「imageFilterUpdating」と呼ばれるインスタンス BOOL も定義されています。

.m の関連部分は次のとおりです。

- (IBAction)hueValueChangedAction:(id)sender {
    if (!imageFilterUpdating) {
        [self performSelectorInBackground:@selector(sliderValueChanged) withObject:nil];
    }
}

- (IBAction)brightnessValueChangedAction:(id)sender {
    if (!imageFilterUpdating) {
        [self performSelectorInBackground:@selector(sliderValueChanged) withObject:nil];
    }
}

- (void)sliderValueChanged {
    imageFilterUpdating = YES;

    if (inputImage == nil)
        inputImage = [[CIImage alloc] initWithImage:self.imageWithoutOverlayView.image];

    if (brightnessFilter == nil) {
        brightnessFilter = [CIFilter filterWithName:@"CIExposureAdjust"];
        [brightnessFilter setDefaults];
        [brightnessFilter setValue: inputImage forKey: @"inputImage"];
    }

    [brightnessFilter setValue: [NSNumber numberWithFloat:self.brightnessSlider.value] forKey: @"inputEV"];

    [self setOutputImage:[brightnessFilter valueForKey: @"outputImage"]];

    if (ccontext == nil)
        ccontext = [CIContext contextWithOptions:nil];

    CIImage *editedInputImage = [[CIImage alloc] initWithCGImage:[ccontext
                                                              createCGImage:outputImage
                                                              fromRect:outputImage.extent]];

    if (hueFilter == nil) {
        hueFilter = [CIFilter filterWithName:@"CIHueAdjust"];
        [hueFilter setDefaults];
    }
    [hueFilter setValue: editedInputImage forKey: @"inputImage"];
    [hueFilter setValue: [NSNumber numberWithFloat:self.hueSlider.value] forKey: @"inputAngle"];

    [self setOutputImage:[hueFilter valueForKey: @"outputImage"]];

    UIImage *endImage = [[UIImage alloc] initWithCGImage:[ccontext
                                                      createCGImage:outputImage
                                                      fromRect:outputImage.extent]];
    self.imageWithoutOverlayView.image = endImage;

    [self setOutputImage:nil];
    imageFilterUpdating = NO;
}

- (void)didReceiveMemoryWarning {
    self.brightnessSlider.enabled = NO;
    self.hueSlider.enabled = NO;
    [super didReceiveMemoryWarning];

    while (imageFilterUpdating); // this is because if you set the other parts nil in the middle of updating the image filter, the app crashes
    [self setHueFilter:nil];
    [self setBrightnessFilter:nil];
    [self setCcontext:nil];
    [self setOutputImage:nil];
    self.brightnessSlider.enabled = YES;
    self.hueSlider.enabled = YES;
}

ユーザーがスライダーを無限に使用できるように、メモリをより効率的にクリアするのを手伝ってくれる人はいますか? それ以外の場合、このコードはすべて正常に機能します。

[UIImage imageNamed:@""]のようなものを使用するよりもARCがそれをはるかにうまく処理している多くの場所で読んだので、私はできる限りのものを割り当て/初期化しようとしました。一部は役に立ちましたが、多くの編集を行った後でもアプリがクラッシュします。メソッドが実行されるたびに新しい変数を作成するのではなく、インスタンス変数の再利用も開始しました。これも役立つようですが、100% ではありません。

UISliders は連続するように設定されていますが、これは私が変更したくないものです。

ありがとう

4

2 に答える 2

4

実行するたびに、自動的にリリースされず、ARC によって管理されない[ccontext createCGImage:outputImage fromRect:outputImage.extent]を作成しています。CGImageRefそれを独自の変数に引き出し、CGImageRelease()作成後に解放しますeditedInputImage

CGImageRef tempImage = [ccontext createCGImage:outputImage fromRect:outputImage.extent];
CIImage *editedInputImage = [[CIImage alloc] initWithCGImage:tempImage];
CGImageRelease(tempImage);
于 2012-09-26T18:50:31.967 に答える
0

作成したさまざまな画像を破棄していないようです。editedInputImage少なくともリリースする必要があります。

于 2012-09-26T02:20:13.023 に答える