Проблема с Objective-C при выпуске iPhone
-
03-07-2019 - |
Вопрос
У меня проблема в том, что я получаю EX_BAD_ACCESS при вызове release для объекта NSStream в моем dealloc на iPhone.
Следующий код
- (void)dealloc {
DLog(@"dealloc started for: %@",self);
@synchronized(self) {
lookupCount--;
if (lookupCount==0) {
UIApplication* app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
}
}
DLog(@"inStream retain count before release: %d",[inStream retainCount]);
[inStream release];
DLog(@"outStream retain count before release: %d",[outStream retainCount]);
[outStream release];
[queryToSend release];
[resultString release];
[data release];
[super dealloc];
NSLog(@"dealloc finsihed for : %@",self);
}
сбой с EX_BAD_ACCESS в [выпуске outstream];линия.
Выходные данные журнала выглядят следующим образом
2009-04-29 13:16:28.547 App[30580:20b] -[SimpleQuery dealloc] [Line 160] dealloc started for: <SimpleQuery: 0x56e540>
2009-04-29 13:16:28.547 App[30580:20b] -[SimpleQuery dealloc] [Line 168] inStream retain count before release: 1
2009-04-29 13:16:28.548 App[30580:20b] -[SimpleQuery dealloc] [Line 170] outStream retain count before release: 1
Интересно, есть ли у кого-нибудь какие-нибудь идеи, почему это может быть?
Решение
В комментарии вы сказали это о outstream
Он создается вызовом getStreamsToHostNamed:port:InputStream:OutputStream:который не должен возвращать автоматически выпущенные объекты я не думаю.
На самом деле это автоматический выпуск.Если вы не сохраняете этот объект где-то в своем коде, вы не несете ответственности за управление его памятью.
Вам следует взглянуть на Рекомендации по управлению памятью Apple.
Многие классы предоставляют методы вида +имя_класса...который вы можете использовать для получения нового экземпляра класса.Часто называемые “удобными конструкторами”, эти методы создают новый экземпляр класса, инициализируют его и возвращают для использования.Хотя вы можете подумать, что вы несете ответственность за освобождение объектов , созданных таким образом, это не так в соответствии с политикой Cocoa set—имя метода не содержит "выделить" или "скопировать", или начинать с "создать".Поскольку класс создает новый объект, он отвечает за удаление нового объекта.
Другие советы
Некоторые потенциальные проблемы:
- Вы блокируете self для выполнения цикла уменьшения lookupCount, что, я полагаю, означает, что вы ожидаете, что этот код будет выполняться из разных потоков.Это должно быть красным флажком прямо здесь, поскольку, если вы освобождаете экземпляр из двух потоков одновременно, один из этих потоков в конечном итоге попытается освободить уже освобожденный экземпляр.
- Финальный
NSLog
вызов попытается напечататьself
который уже был бы освобожден.
Я знаю, что ни одно из них не относится конкретно к [outStream release]
, но они могут быть связаны.Возможно, вы захотите попробовать отладить это с помощью Подключенный NSZombieEnabled чтобы получить больше информации.
Кроме того, убедитесь, что отпустили inStream
также неявно освобождает outStream
, и т.д.