сообщение об освобождении, отправленное освобожденному экземпляру, но указатель экземпляра не равен нулю

#objective-c #memory-management

#objective-c #управление памятью

Вопрос:

Вот код в одном из моих методов, где imageRaw — это ivar:

 if (imageRaw) 
    [imageRaw release]; // error occurs here
    .
    .
    .
if (anImage) 
    imageRaw = [[anImage scaleToFitWithin:maxImageSize interpolationQuality:kCGInterpolationHigh] retain];          
  

У меня иногда возникали ошибки такого типа, и я действительно этого не понимаю. Единственный способ, которым он не равен нулю, — это присвоение экземпляру правильного класса, в данном случае UIImage .

Зомби включены.

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

Ответ №1:

Я предполагаю, что здесь происходит то, что в какой-то момент вашего выполнения этот метод вызывается, когда у вас что-то хранится, imageRaw но ничего нет anImage . В этом случае ваш объект в imageRaw будет освобожден, но в нем не будет сохранено ничего нового. При этом адрес памяти для освобожденного объекта остается в imageRaw , но объект больше не существует. Затем, при следующем запуске метода, он проверяет, не равен ли imageRaw он нулю (что и есть, поскольку он все еще хранит этот адрес памяти), пытается вызвать release эту память и завершается неудачей. Чтобы избежать этого, вы можете убедиться, что для него установлено imageRaw значение nil каждый раз, когда вы вызываете release:

 if (imageRaw)
    [imageRaw release];
    imageRaw = nil;
    .
    .
    .
if (anImage)
    imageRaw = . . .
  

Комментарии:

1. Спасибо, Шон. Я проверил свои методы в присваивании imageRaw = на наличие каких-либо авторелизов, что, я думаю, вызывало подобные проблемы в прошлом. Я ничего не видел. Итак, я тестирую с вашей рекомендацией. Потребуется некоторое время для тестирования, прежде чем я смогу сказать, что проблема решена, но я опубликую здесь, как только узнаю, разрешило ли это ее.