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 или более).
, на какой линии происходит плохой доступ? – sergio
Это происходит только в том случае, если у меня есть self.spectrogramView.image = line. Если я прокомментирую это, представление бесполезно, но оно не сработает (хотя модель все еще сохраняет изображение в своем собственном ivar). Это правда, даже если я переключу переданный объект из UIImage * в CGImageRef. –
ОК, поэтому я думаю, вы должны опубликовать код, где вы: alloc/init 'spectrogramView' и все, что у вас есть с этим объектом; alloc/init 'currentModel' и все, что вы делаете с этим объектом ... – sergio