Я пытаюсь применить несколько эффектов к изображениям. Я создал отдельный файл для обработки обработки эффектов, который я могу отправить UIImageView
и получить измененную копию. Чтобы сохранить время обработки, я сначала загружаю изображение в отдельный файл обработки и сохраняю его в памяти, а не загружаю изображение каждый раз, когда я его модифицирую. Поток - getImageData -> modifyRGB -> displayImage. Все работает до последнего шага. Возвращенное измененное изображение отображается на экране в течение секунды, а затем Xcode выдает ошибку EXEC_BAD_ACCESS
: код 1. Я неоднократно повторял код и не могу найти проблему. Любая помощь приветствуется. Спасибо!Приложение Сбой при попытке обновления UIImageView после изменения значений RGB для проекта iOS
ОБНОВЛЕНИЕ С ПОДРОБНЕЕ
Я использую Xcode 4.3.1 с автоматическим подсчетом ссылок
Использование разрывов строк, я могу подтвердить, что авария происходит, когда линия self.imageView.image = [self.imageManipulation displayImage]; Выполняется. Изображение обновляется, но затем программа сразу же падает. Использование NSZombie, я получаю сообщение об ошибке - [Not A Тип сохранения]: сообщение, отправленное на освобождаться например 0x2cceaf80
С моей ViewController я использую:
[self.imageManipulation getImageData:self.imageView.image];
[self.imageManipulation modifyRGB];
self.imageView.image = [self.imageManipulation displayImage];
Мой файл ImageManipulation состоит из:
@implementation ImageManipulation
static unsigned char *rgbaDataOld;
static unsigned char *rgbaDataNew;
static int width;
static int height;
- (void)getImageData:(UIImage *)image
{
CGImageRef imageRef = [image CGImage];
width = CGImageGetWidth(imageRef);
height = CGImageGetHeight(imageRef);
rgbaDataOld = malloc(height * width * 4);
rgbaDataNew = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rgbaDataOld, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
CGImageRelease(imageRef);
}
//modify rgb values
- (void)modifyRGB
{
for (int byteIndex = 0 ; byteIndex < width * height * 4; byteIndex += 4)
{
rgbaDataNew[byteIndex] = (char) (int) (rgbaDataOld[byteIndex]/3) + 1;
rgbaDataNew[byteIndex+1] = (char) (int) (rgbaDataOld[byteIndex+1]/3 + 1);
rgbaDataNew[byteIndex+2] = (char) (int) (rgbaDataOld[byteIndex+2]/3) + 1;
rgbaDataNew[byteIndex+3] = (char) (int) 255;
}
}
//set image
- (UIImage *)displayImage
{
CGContextRef context;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
context = CGBitmapContextCreate(rgbaDataNew, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast);
CGImageRef imageRef = CGBitmapContextCreateImage (context);
UIImage *outputImage = [UIImage imageWithCGImage:imageRef];
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
CGImageRelease(imageRef);
return outputImage;
}
@end
Обычно Excess_Bad_Access приходит, если вы обращаетесь к данным, которые были выпущены или объект не имеет ссылки на него. Проверьте свой код для выделения и отпускания на объекте, на котором возникает исключение. –
К сожалению, ваш вопрос слишком широк. Установили ли некоторые точки останова для сужения при ошибке? Вы скользнули слайдер сжатия списка потоков вправо в Навигаторе отладки, чтобы увидеть большую часть стека в момент выброса исключения или введите «bt» (для «backtrace») в lldb (или gdb)? Как сказал roronoa, вероятно, из-за попытки получить доступ к тем, что уже выпущено, но некоторые базовые отладки, чтобы сузить его, либо ответят на него за вас, либо, по крайней мере, дадут нам достаточно подсказок, чтобы помочь. –
Я попытаюсь сузить его дальше. Сбой происходит при выполнении строки ** self.imageView.image = [self.imageManipulation displayImage]; **. И, несмотря на то, что он выходит из строя на этой линии, затемненное измененное изображение все еще отображается, но только на долю секунды перед сбоем. Метод ** [self.imageManipulation displayImage] ** выполняется полностью - проверяется с помощью контрольных точек. Я буду продолжать проверять. –