NSZombie включил взлом рабочего кода? - PullRequest
0 голосов
/ 07 июня 2010

У меня есть следующий метод в UIImageManipulation.m:

+(UIImage *)scaleImage:(UIImage *)source toSize:(CGSize)size
{
    UIImage *scaledImage = nil;
    if (source != nil)
    {
        UIGraphicsBeginImageContext(size);
        [source drawInRect:CGRectMake(0, 0, size.width, size.height)];
        scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return scaledImage;
}

Я звоню по-другому:

imageFromFile = [UIImageManipulator scaleImage:imageFromFile toSize:imageView.frame.size];

(imageView - это UIImageView, выделенный ранее)

Это прекрасно работает в моем коде. Я отлично изменяю размер изображения и выкидываю ноль ошибок. У меня также нет ничего всплывающего при сборке -> анализировать. Но когда я включаю NSZombieEnabled для отладки другой проблемы EXC_BAD_ACCESS, код ломается. Каждый раз. Я могу выключить NSZombieEnabled, код работает отлично. Я включаю его и бум. Разбитый. Я закомментирую звонок, и он снова работает. Каждый раз, это дает мне ошибку в консоли: -[UIImage release]: message sent to deallocated instance 0x3b1d600. Эта ошибка не появляется, если `NSZombieEnabled выключен.

Есть идеи?

- EDIT -

Хорошо, это убивает меня. Я застрял точки останова везде, где я могу, и я до сих пор не могу овладеть этой вещью. Вот полный код, когда я вызываю метод scaleImage:

-(void)setupImageButton
{
    UIImage *imageFromFile;

    if (object.imageAttribute == nil) {
        imageFromFile = [UIImage imageNamed:@"no-image.png"];
    } else {
        imageFromFile = object.imageAttribute;
    }
    UIImage *scaledImage = [UIImageManipulator scaleImage:imageFromFile toSize:imageButton.frame.size];
    UIImage *roundedImage = [UIImageManipulator makeRoundCornerImage:scaledImage :10 :10 withBorder:YES];
    [imageButton setBackgroundImage:roundedImage forState:UIControlStateNormal];
}

Другой метод UIImageManipulator (makeRoundCornerImage) не должен вызывать ошибку, но на случай, если я что-то упустил, я выкинул весь файл на github здесь .

Хотя что-то в этом методе. Должно быть. Если я это прокомментирую, это прекрасно работает. Если я оставлю это, Ошибка. Но он не выдает ошибок при отключенном NSZombieEnabled.

Ответы [ 2 ]

3 голосов
/ 08 июня 2010

Целью NSZombieEnabled является обнаружение сообщений, которые отправляются объектам после их освобождения. Вы видите консольную ошибку NSZombieEnabled, сообщающую, что сообщение release отправляется освобожденному экземпляру UIImage. Обычно такая ошибка является результатом слишком большого количества звонков на release или недостаточного количества звонков на retain.

В этом случае ваш scaleImage:toSize: метод возвращает автоматически выпущенный UIImage. Сообщение об ошибке, которое вы получаете от NSZombieEnabled, предполагает, что вы можете освобождать этот объект после того, как он будет возвращен. Это объяснит вашу ошибку. Когда ваш пул авто-релиза истощается, он пытается освободить объект, который уже был освобожден.

Вы передаете imageFromFile в scaleImage:toSize:, а затем переназначаете эту же переменную возвращаемому значению. В этой идиоме нет ничего плохого, но она требует особого внимания, чтобы избежать ошибок памяти, подобных этой. Вы перезаписываете свою ссылку на исходный объект, поэтому вам нужно либо убедиться, что он автоматически освобожден до назначения, либо сохранить отдельную ссылку, которую можно вручную разблокировать после назначения. В противном случае ваш оригинальный объект протечет.

0 голосов
/ 11 июня 2010

Ошибка произошла из-за выпуска, происходящего в методе makeRoundedCornerImage из UIImageManipulator. До сих пор не уверен, почему его не подцепили без включенного NSZombieEnabled, но это то, что было.

Вы можете найти оскорбительную строку в Гисте, которую я разместил в исходном вопросе: Строка 74.

...