2011-08-09 2 views
1

FIXED: Я еще не уверен, почему. Код был обновлен ниже, а примечания внизуCGImage/UIImage pass причины EXE-BAD-ACCESS

У меня очень странная ошибка, которая не отображается на симуляторе (даже при работе с инструментами), если я не включу все параметры Zombie и Debug. Однако после минуты обновления он будет разбивать телефон (1 обновление в секунду). У меня есть 2D-массив, в котором я беру подмножество, применяю цветовой код и превращаюсь в изображение (этот массив постоянно меняется). Затем я передаю это изображение модели, и viewcontroller захватывает его из модели после получения уведомления об обновлении. Я макет 3 классов -Spectrogram, модель, ViewController:

Вот важные биты каждого (есть больше, но не имеет отношения):

Spectrogram.h (К сожалению, я не могу это правильно отступы здесь)

@interface: Spectrogram : NSObject 
{ 
    NSMutableData *arrayData; 
} 
//renamed so Xcode allows the object with +1 reference count to be returned 
- (CGImageRef)newSpectrogramImage; 

Spectrogram.m

@implementation Spectrogram 
- (CGImageRef)newSpectrogramImage 
{ 
    //slightly reordered 
    NSMutableData *imageData = [[NSMutableData alloc] init]; 
    ...code to go through arrayData and colormap it (get RGB transform) and store in imageData... 
    CGImageRef arrayImage = nil; 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    //specifically tell CGImage there is no alpha channel 
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNone; 
    //Use the toll-free bridge between NSData and CFData 
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)imageData); 
    arrayImage = CGImageCreate((slices-startSlice), bins, 8, 24, 3*(slices-startSlice), colorSpace, bitmapInfo, provider, NULL, false, kCGRenderingIntentDefault); //image is rotated now, so width and height are switched 
    CGColorSpaceRelease(colorSpace); 
    CGDataProviderRelease(provider); 
    CGImageRelease(arrayImage); 
    [imageData release]; 
    //Pass the CGImageRef with a reference count of 1 
    return arrayImage; 
} 

model.h

@interface: Model : NSManagedObject 
{ 
    Spectrogram *spectrogram; 
} 
//Function the viewController can call to get the update 
- (CGImageRef)newSpectrogramImage; 

Model.m

@implementation Model 
... there is a function that adds new data to the array and notifies all listeners... 
- (CGImageRef)newSpectrogramImage { 
    return [spectrogram newSpectrogramImage]; 
} 

ViewController.h

@interface: ViewController : UIViewController 
{ 
} 
//the root controller actually alloc's the record, and sets this property when creating this view 
@property (nonatomic, retain) Record *currentRecord; 

ViewController.m

@implementation ViewController 
@synthesize spectrogramView; 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [[NSNotificationCenter ... listen for model updates... 
} 

//now, the real meat 
- (void)recordUpdated:(NSNotification*)notification 
{ 
    CALayer *myLayer = self.view.layer; 
    CGImageRef spectrogramImage = nil; 
    spectrogramImage = [currentRecord newSpectrogramImage]; 
    myLayer.contents = (id)spectrogramImage; 
    CGImageRelease(spectrogramImage); 
} 

Я изменил это так много раз в последний день, пытаясь выследить где и почему это терпит неудачу. Вместо этого я попытался передать CGImageRef (но поскольку это не объект, я беспокоюсь о том, чтобы сделать копии того, что может быть «огромным изображением»), и он все еще не работает. И он отлично работает в симуляторе (будет работать десятки минут). Но не удается в течение минуты на iphone, или если я включу параметры отладки для симулятора (он сработает, как только загрузится диспетчер представлений).

На стороне примечание, это может быть полезно. Этот viewcontroller загружается как модальный вид, когда телефон поворачивается вбок (отлично работает). Тем не менее, у меня много NSLogs, и я вижу, что dealloc viewcontroller вызывается до того, как mainviewcontroller даже получит viewwilldisappear, но он все еще работает. И затем dealloc этого контроллера вызывается снова, когда телефон повернут назад, и вид исчезнет.

Примечание версия, которая работала хорошо в тренажере прошел CGImageRefs весь путь к ViewController, вместо UIImages. Я пробовал по меньшей мере 50 различных комбинаций, где можно создать UIImage из CGImage, и то, что выложено выше, является лишь одним из них (все они терпят неудачу в конечном итоге или сразу). Следует отметить, что с выше коде, если я добавить это к ViewController modelUpdated:

CGSize size = currentModel.spectrogramImage.size; 
NSLog(@"width: %f", size.width); 

и закомментируйте присвоив ее spectrogramView, ширина сообщается правильно, так что UIImage становится передается вместе, это просто не сохраняя (я понимаю ошибку EXE_BAD_ACCESS).

Кроме того, в последнее время я получаю дан EXE_BAD_ACCESS на линии

self.spectrogramImage = [spectrogram getSpectrogramImage]; 

. Итак, я думаю, что ошибка может быть внутри класса Spectrogram. Несмотря на то, что код CGImage и UIImage был взят из примеров Apple.

Фиксированные примечания Я прочитал, что установка содержание CALayer был гораздо более быстрый способ, чтобы передать CGImageRef на вид - и не UIImage посредника. К сожалению, я только совершаю рабочие изменения, поэтому я не вижу каждую итерацию, через которую я прошел. Тем не менее, я знаю, что у меня было что-то очень похожее на это несколько раз, которое продолжало рушиться. Проблема всегда заключалась в том, что, поскольку она в настоящее время написана, программа вылетает с EXE_BAD_ACCESS. И если бы я поднял счетчик ссылок (или не выпустил его), тогда он будет работать отлично, но объект будет течь. Я до сих пор не понимаю, как это возможно. Чтобы иметь разницу между утечкой и BAD ACCESS, должно быть количество ссылок 1 (а не 2 или более).

+0

, на какой линии происходит плохой доступ? – sergio

+0

Это происходит только в том случае, если у меня есть self.spectrogramView.image = line. Если я прокомментирую это, представление бесполезно, но оно не сработает (хотя модель все еще сохраняет изображение в своем собственном ivar). Это правда, даже если я переключу переданный объект из UIImage * в CGImageRef. –

+0

ОК, поэтому я думаю, вы должны опубликовать код, где вы: alloc/init 'spectrogramView' и все, что у вас есть с этим объектом; alloc/init 'currentModel' и все, что вы делаете с этим объектом ... – sergio

ответ

1

Я не могу ответить на ваш конкретный вопрос, но это может помочь вам узнать, что происходит немного лучше. У меня есть функция logMemUsage, которая выводит ваше использование памяти и показывает, насколько она изменилась с последнего раза. Если вы назовете его примерно секунду или около того, вы можете лучше понять, как память используется в вашем приложении. Если он будет расти, очевидно, что есть утечка, если он идет вверх и вниз, как вы ожидаете, это хорошо, если он не опустится, когда вы думаете, что это нужно, вы это увидите. Он находится в github here в Utilities.h/.m

+0

Я наблюдал за использованием памяти в инструментах, и он растет, как ожидалось (~ 1 МБ/ч). Массивы (есть 3) постоянно добавляются к полученным данным - это часть дизайна, это приложение для анализа. Когда текущая запись закрыта, я делаю некоторую очистку для сжатия данных, которые хранятся в Core Data, и когда запись просматривается, я разжимаю или восстанавливаю производные данные (например, массив спектрограмм и изображение). Инструменты также говорят, что объекты не протекают. Я читал, что Quartz2D может быть проблематичным с памятью. –

1

Трудно понять это из того, что вы опубликовали, но почему бы не использовать свойства с сохранением всех ваших выделенных данных? Например, вы возвращаете авторизованный UIImage из getSpectrogramImage, и он хранится в Модели с вызовом self.spectrogramImage = [spectrogram getSpectrogramImage] ;, но не существует свойства для spectrogramImage в любом месте, где я вижу, используя само. механизм. Это просто, что вы не потрудились публиковать его? То, как это написано, может быть получено автореализацией, а затем, когда вы пытаетесь его использовать ...

+0

+1, 'spectrogramImage' в' Model' нуждается в '@property (сохранить)'. – darvids0n

+0

Извините, model.h был написан неправильно (всего это касается подготовки к вырезанию и вставке и выполнения некоторых операций из памяти), spectrogramImage сохраняется. –

Смежные вопросы