Получение ошибки по умолчанию (EXC_BAD_ACCESS) при освобождении переменных - PullRequest
3 голосов
/ 19 февраля 2009

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

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

.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 alt text

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

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

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

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

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

Спасибо

Dan

Ответы [ 5 ]

13 голосов
/ 19 февраля 2009

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

2 голосов
/ 13 марта 2009

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

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

0 голосов
/ 12 июня 2009

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

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

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

0 голосов
/ 12 июня 2009

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

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

0 голосов
/ 22 февраля 2009

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

- (Недействительными) 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#BasicUsage

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

scan-build -k -V xcodebuild

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

С уважением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...