Получение ошибки по умолчанию (EXC_BAD_ACCESS) при освобождении переменных

Хорошо, я понимаю, что эта ошибка в основном возникает при отправке вызова метода или при попытке получить доступ к переменной, которая уже была освобождена.

Вот проблема:

.h
@interface TimeEntry : NSObject <NSCopying, NSCoding> {

NSDate *from;
NSDate *to;

NSString *information;


}

@property (nonatomic, retain) NSDate *from;
@property (nonatomic, retain) NSDate *to;

@property (nonatomic, copy) NSString *information;

@end

И дело моих классов.

-(void)dealloc{

    [super dealloc];    
    [to release];
    [from release];
    [information release];

}

Это вещь трассировки, когда я получаю ошибку EXC_BAD_ACCESSальтернативный текст

Итак, я отправляю сообщение объекту, который был освобожден, верно?

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

В приведенном выше методе dealloc, если я закомментирую [для выпуска] и [из выпуска], приложение не вылетает. Если я закомментирую только один из них... он не рухнет. В окне отладки к и от имеют разные адреса памяти.

Как управление памятью может быть таким сложным!!!!

Есть какие-нибудь подсказки?

Спасибо,

Дэн

5 ответов

Решение

Отправьте сообщение [super dealloc] после того, как вы освободили свои переменные, а не раньше. [super dealloc] должен быть последним, что вы делаете в своем методе dealloc.

Обратите внимание, что вы можете отправить [nil release], и ​​приложение не будет аварийно завершено. так что проверка на ноль перед выпуском - это то, что не нужно.

но я согласен, что вы должны сделать [super dealloc] в конце процедуры dealloc.

Свойства текущего объекта хранятся в объекте.

Когда вы вызываете [super dealloc], вы говорите системе уничтожить объект. После этого вызова вы не можете больше полагаться на существующие свойства или исправлять их.

Как уже говорилось, звоните после того, как освободите других участников.

Терри прав, [super dealloc] звонок всегда должен быть последним -dealloc,

Чтобы быть более конкретным, звоню -[NSObject dealloc] это то, что освобождает память для объекта. (В вашем случае вы напрямую расширяете NSObject, но более глубокие деревья наследования создают цепочку вызовов dealloc.) В общем смысле вызов родительского объекта -dealloc Сначала метод освободит ресурсы, унаследованные от родителя. Если ребенок зависит от какого-либо из этих ресурсов, когда он освобождает свои собственные, вы попадаете в русло. Поскольку родитель не может зависеть от ребенка, в первую очередь устранение дочерних ресурсов является правильным и безопасным способом выполнения действий.

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

- (недействительными) dealloc {

if(to != nil{ 
   NSLog(@"releasing: %@", to);
   [to release];
}

if(from != nil{
   NSLog(@"releasing: %@", from);
   [from release];
}

if(information != nil){
   NSLog(@"releasing: %@", information);
   [information release];
}

[super dealloc]; 

}

Кроме того, вы можете загрузить, установить и использовать средство проверки CLANG, чтобы понять, почему ваш код неверен. Этот инструмент (который уже создан для Leopard 10.5.x) иногда может не дать правильного ответа, но по моему личному опыту он никогда не подводил. Я настоятельно рекомендую его как один из ваших ежедневных инструментов разработки.

Вы можете скачать его с

http://clang.llvm.org/StaticAnalysis.html

Использование это действительно просто. Взгляни на

http://clang.llvm.org/StaticAnalysisUsage.html

На практике вы просто создаете свой проект XCode с помощью команды

scan-build -k -V xcodebuild

затем вы проверяете полученные выходные HTML-файлы с помощью команды, которая будет отображаться в окне вашего терминала. Эти файлы дадут вам подробное объяснение того, почему что-то не так в вашем коде.

С уважением

Другие вопросы по тегам