2012-09-26 31 views
2

我想讓用戶使用一些使用CIFilters影響UIImageView中的圖像的滑塊來編輯色調和亮度。UISlider和CIFilter導致應用程序在使用太多後崩潰

我有它工作得很好,但有一個問題:如果滑塊使用太多,內存警告開始彈出,然後,如果用戶繼續嘗試後,應用程序退出,但沒有'一個崩潰日誌(由此超級困惑)。

我對編程還很陌生,尤其是對內存管理方面的新手,但希望這裏有人能提供幫助。

這裏是我的代碼:

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

而且我也有一個實例BOOL定義了一個名爲 「imageFilterUpdating」

這裏有.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

每次運行[ccontext createCGImage:outputImage fromRect:outputImage.extent]時,都會創建一個CGImageRef,它不會自動發佈,也不會由ARC進行管理。在創建editedInputImage之後,將它拉出到自己的變量中並使用CGImageRelease()釋放它。

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

非常感謝你! – user1698766

0

它看起來像你沒有處置你創建的各種圖像。您至少需要發佈editedInputImage

+0

我正在使用自動引用計數,所以釋放的東西應該自動完成(如果我嘗試自己釋放某些東西,我實際上會在Xcode中發生錯誤)。 – user1698766

+0

啊,我誤解了你寫的關於ARC的內容。對於那個很抱歉。你運行泄漏儀器嗎? – user1118321

+0

我剛剛做到了。當我移動滑塊時,「CFData(存儲)」類別的填充速度非常快,否則不會移動。我一直在搜索,但到目前爲止,我還沒有想出任何解決我的問題。 – user1698766