2

我试图让用户选择使用几个滑块来编辑色调和亮度,这些滑块使用 CIFilters 来影响 UIImageView 中的图像。

我让它工作得很好,但有一个问题:如果滑块使用过多,内存警告开始弹出,然后,如果用户在那之后继续尝试,应用程序退出,但没有崩溃日志(???对此超级困惑)。

我对编程还是很陌生,尤其是对内存管理很陌生,但希望这里有人可以提供帮助。

这是我的代码:

在我的 .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;
}

谁能帮我更有效地清理内存,以便用户可以无限使用滑块?否则,此代码一切正常。

我已经尝试过尽可能分配/初始化东西,因为我在很多地方读到 ARC 比使用 [UIImage imageNamed:@""] 之类的东西要好得多,而且似乎帮助了一些人,但经过大量编辑后,该应用程序仍然崩溃。我也开始重用实例变量,而不是每次运行方法时都创建新变量,这似乎也有帮助,但不是 100%。

UISliders 设置为连续的,这是我不想改变的。

谢谢

4

2 回答 2

4

每次运行时,[ccontext createCGImage:outputImage fromRect:outputImage.extent]您都会创建一个CGImageRef不会自动发布且不受 ARC 管理的文件。将其拉出到它自己的变量中,并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 回答