【问题标题】:UISlider and CIFilter causes app to crash after too much useUISlider 和 CIFilter 导致应用程序在使用过多后崩溃
【发布时间】:2012-09-17 13:21:56
【问题描述】:

我试图让用户选择使用几个滑块来编辑色调和亮度,这些滑块使用 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%。

UISlider 设置为连续的,这是我不希望更改的内容。

谢谢

【问题讨论】:

    标签: objective-c ios uislider core-image cifilter


    【解决方案1】:

    每次运行[ccontext createCGImage:outputImage fromRect:outputImage.extent] 时,您都会创建一个CGImageRef,该CGImageRef 不会自动发布且不受ARC 管理。在创建editedInputImage 后,将其拉出到它自己的变量中并使用CGImageRelease() 释放它。

    CGImageRef tempImage = [ccontext createCGImage:outputImage fromRect:outputImage.extent];
    CIImage *editedInputImage = [[CIImage alloc] initWithCGImage:tempImage];
    CGImageRelease(tempImage);
    

    【讨论】:

      【解决方案2】:

      您似乎没有处理自己创建的各种图像。你至少需要释放editedInputImage

      【讨论】:

      • 我正在使用自动引用计数,所以应该自动释放一些东西(如果我尝试自己释放一些东西,我实际上会在 Xcode 中得到一个错误)。
      • 啊,我误解了你写的关于 ARC 的内容。对于那个很抱歉。您是否运行过检漏仪?
      • 我刚做了。当我移动滑块时,“CFData(存储)”类别会很快填满,否则不会移动。我一直在谷歌上搜索它,但到目前为止,我还没有想出任何办法来解决我的问题。
      • 它应该给你一个堆栈跟踪,这样你就可以看到它来自哪里。堆栈跟踪说明了什么?
      猜你喜欢
      • 2020-09-27
      • 1970-01-01
      • 2014-04-10
      • 2019-02-10
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 2015-10-21
      • 2016-06-04
      相关资源
      最近更新 更多