Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование iOS/iPhone
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
Veyron
106 / 106 / 9
Регистрация: 02.06.2009
Сообщений: 578
1

Есть ли здесь утечка памяти?

06.07.2013, 13:24. Просмотров 1476. Ответов 16
Метки нет (Все метки)

Вот код:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-(NSString *)getCookie
{
    NSMutableURLRequest *cookieRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://google.ru"]];
    [cookieRequest setHTTPMethod:@"GET"];
    
    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    
    [NSURLConnection sendSynchronousRequest:cookieRequest returningResponse:&response error:&error];
    [cookieRequest release];
    if (error != nil)
    {
        [error release];
        return nil;
    }
    else
    {
        [error release];
        return [[[response allHeaderFields] objectForKey:@"Set-Cookie"] substringToIndex:[[[response allHeaderFields] objectForKey:@"Set-Cookie"] rangeOfString:@";"].location];
    }
}
Есть ли здесь утечка памяти? Особенно интересует момент с возвратом - уничтожится ли response или нет?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2013, 13:24
Ответы с готовыми решениями:

Утечка памяти - Received memory warning?
Всем привет! Подскажите как можно решить проблему и где я делаю ошибки? ...

Есть ли утечка памяти?
Пример добавления элемента в список. // Включение в список нового компонента...

Есть ли тут утечка памяти?
Добрый вечер. Случайно возник такой вопрос: а вызывается ли деструктор для уже...

Есть ли утечка памяти в list
Здравствуйте, форумчане, есть вопрос насчет освобождения памяти в list, каждый...

Есть ли утечка памяти в этом случае?
_Доброго денёчка всем. Прохожу тему на указатели и ссылки. Делаю упражнение на...

16
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
06.07.2013, 13:35 2
сделай product->analyze и он все покажет(очень удобно быстро проверить на наличие возможных проблем). Или в instruments проверь
2
Pro2005
44 / 44 / 3
Регистрация: 27.05.2013
Сообщений: 163
06.07.2013, 15:19 3
Однозначно есть...
ты посылаешь объектам сообщение release... хотя ты им не делал alloc/retain...
0
Veyron
106 / 106 / 9
Регистрация: 02.06.2009
Сообщений: 578
06.07.2013, 17:47  [ТС] 4
Прогон анализатором показал, что cookieRequest релизить не надо.
Pro2005, а почему релиз error - неверный? Я просто думал, что стандартные конструкторы и функции автоматически делают alloc встроенным типам.
Я просто только начинаю с Obj-C, поэтому не совсем понял механизма работы с памятью. Не подскажете, локальные переменные автоматически освобождаются при выходе из тела метода? Если нет - как быть с response?
Посоветуйте, пожалуйста, где можно подробно ознакомиться с механизмом работы с памятью в Objective-C :-)

Добавлено через 2 минуты
Pro2005, и, насколько я понял и пробовал - release невыделенного объекта не вызывает утечки. У меня просто вылетала ошибка неверного обращения к памяти. Меня интересует утечка именно в смысле потери выделенного места (без его возврата в пул), которая скорее всего будет для response.
0
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
06.07.2013, 18:02 5
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Veyron Посмотреть сообщение
Не подскажете, локальные переменные автоматически освобождаются при выходе из тела метода? Если нет - как быть с response?
для того что бы не было утечек в таких случаях посылается autorelease
а вообще вот тут все подробно написано
3
Veyron
106 / 106 / 9
Регистрация: 02.06.2009
Сообщений: 578
06.07.2013, 19:19  [ТС] 6
Xavier, и правда, статьи там очень хороши. Что ни говори - официальная документация всегда лучше всего :-)

Однако я не нашел ответ на один свой вопрос:
Objective-C
1
2
NSNumber *number = [[NSNumber alloc] init];
NSNumber *number_too = number;
Какой тогда будет счетчик ссылок на этот объект?
0
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
06.07.2013, 19:34 7
так и останется 1 ты просто указываешь number_too и number на один и тот же объект не увеличивая при этом счетчика ссылок. Вообще можешь проверить послав сообщение retainCount оно как раз возвращает кол-во ссылок
и только если потом ты пошлешь number_too сообщение retain то тогда счетчик будет =2, а вот если ты напишешь [number release] без удержания то потом при попытке обратиться к number_too будет ошибка.
1
noname_club
107 / 98 / 12
Регистрация: 01.05.2013
Сообщений: 603
07.07.2013, 00:31 8
получаем что :

retain увеличивает счетчик
release уменьшает
autorelease уменьшает автоматически по-окончанию блока
присваивание к strong свойству опять увеличивает
при вызове конструктора [[objectClass alloc] init] он же [objectClass new] счетчик ссылок всегда равен 1

поправьте если что неверно
0
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
07.07.2013, 11:55 9
noname_club, По сути все правильно. Только autorelease не уменьшает счетчик а помещает объект в autorelease pool, а вот по окончании блока autorelease pool-а все объекты которые входят в него получают сообщение release, и сообщение release они получают столько же раз сколько получили сообщение autorelease.

Добавлено через 12 минут
А вообще используйте ARC
1
noname_club
107 / 98 / 12
Регистрация: 01.05.2013
Сообщений: 603
07.07.2013, 12:26 10
дополнительно на рассмотрение

1) код без утечек

Objective-C
1
2
3
4
5
6
7
8
9
10
    NSMutableString* s1 = [NSMutableString stringWithFormat:@"Hello"];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
2) код с утечками

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
    NSMutableString* s1 = [NSMutableString new];
    
    
    
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
в обоих случаях счетчик показывает 1, => они должны утекать в обоих случаях, однако течет только в 2

идем дальше
3)

Objective-C
1
2
3
4
5
6
7
8
9
10
    NSMutableString* s1 = [[NSMutableString new] autorelease];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
не течет, чтото мне подсказывает что в методе NSMutableString stringWithFormat уже по-умолчанию стоит autorelease

теперь проверим как ведет себя autorelease при принудительном уменьшении ссылки

4)

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
    NSMutableString* s1 = [[NSMutableString new] autorelease];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
    
    [s1 release]; // << уменьшение ссылки
не получилось EXC_BAD_ACCESS

проверим как ведет себя "скрытый autorelease" в методе stringWithFormat, ведь мы не ожидаем что там он там прописан

5)

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
   NSMutableString* s1 = [NSMutableString stringWithFormat:@"Hello world"];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
    
    [s1 release]; // << уменьшение ссылки
получилось

однако появилась странная надпись

test_ARC(690,0xac1cda28) malloc: *** error for object 0x753ad90: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
что как бы означает что релизить нельзя

чтобы разобраться в сабже идем в гугл и видим там

http://stackoverflow.com/questions/5...ringwithformat
You never release it. It's autoreleased already.

You only ever release objects which were given to you via methods whose names begin with +alloc, +new -copy, -mutableCopy, or -retain. If the name begins with anything else, you don't own it and are not responsible for releasing it.
что дословно означает: Если вы используете в конструкторе +alloc, +new -copy, -mutableCopy, or -retain тогда требуется релизить

------

Из этого можно сделать вывод, что без использования ARC, нужно во всех ваших классах писать конструкторы со словом init

например:

initWithData
initWithObject и прочее чтобы было видно что autorelease не используется.

---

я так гуглу походил, внятного ответа как распознать autorelease объект там нет.
=> только тестированием и использованием статических методов названием с init и прочими, которые указывали что autorelease не используется
0
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
07.07.2013, 13:14 11
Правила довольно простые.
Если тебе нужен объект которым ты будешь владеть, т:е. грубо говоря сам управлять его жизненным циклом, ты должен явно его создать с помощью всего нескольких методов: alloc, init (и все разновидности init по типу initWith...)
или new или же удержать объект с помощью copy или retain. Все эти объекты не будут помещены в autorelease pool пока ты не сам не пошлешь сообщение autorelease. И за этими объектами надо следить, забудешь release или autorelease все утечка.

Все же остальные объекты созданные с помощью "convenience constructors" такими как arrayWaithArray, stringWithString и т.д. , т.е по соглашению не включающие слова: alloc, init, new, будут автоматически помещены в autorelease pool ибо эти методы возвращают по принципу :
Objective-C
1
return [[[NSString alloc] initWithString:@"some string"] autorelease];
2
Veyron
106 / 106 / 9
Регистрация: 02.06.2009
Сообщений: 578
07.07.2013, 21:10  [ТС] 12
Xavier, а где еще можно почитать о спецификаторах в свойствах (assing, weak, retain, strong...) ?
0
noname_club
107 / 98 / 12
Регистрация: 01.05.2013
Сообщений: 603
07.07.2013, 22:19 13
а где еще можно почитать о спецификаторах в свойствах (assing, weak, retain, strong...) ?
Семантика сеттеров свойств

strong - обозначает строгое переназначение объекта, делая указатель на объект владельцем этого объекта

weak - в отличии от strong обозначает нестрогое соответствие и если объект был освобожден из памяти (из другого класса или потока), то значение установится в nil. Не поддерживается OS X v10.6 и iOS 4; используйте assign

copy - указывает на то, что для присваивания будет использована копия переданного объекта. Первоначальному объекту посылается сообщение release. Может быть использовано только для объектов, поддерживающих протокол NSCopying, например NSString.

assign - для задания нового значения используется оператор присваивания. Используется только для скалярных типов (NSInteger и CGRect) либо для объектов, которыми мы не владеем.

retain - укaзывает на тo, что для объекта, используемого в качестве нового значения instance-переменной, управление памятью происходит вручную (не забываем потом освободить память).

Atomic

nonatomic - делает более быстрым способ доступа к объекту в немногозадачной среде, так-как в случае с atomic (по умолчанию все акцессоры atomic) и использованием strong, copy, или retain, во избежание коллизий с возможностью доступа к свойству из других потоков в сеттере строится код блокирующий переключение между потоками.
1
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
07.07.2013, 22:42 14
Цитата Сообщение от Veyron Посмотреть сообщение
а где еще можно почитать о спецификаторах в свойствах (assing, weak, retain, strong...) ?
блин, да в оффициальной документации http://developer.apple.com/library/i...atingData.html

Цитата Сообщение от noname_club Посмотреть сообщение
Из этого можно сделать вывод, что без использования ARC, нужно во всех ваших классах писать конструкторы со словом init
например:
initWithData
initWithObject и прочее чтобы было видно что autorelease не используется.
---
я так гуглу походил, внятного ответа как распознать autorelease объект там нет.
=> только тестированием и использованием статических методов названием с init и прочими, которые указывали что autorelease не используется
к чему пустая трата времени и какие-то лишние выводы?
все же отлично расписано в документации, зачем этот stackoverflow-driven development от таких же "самоучек" как вы?
на блюдечке все ведь разложено, а вы там целую дисертацию навояли и то размытую
https://developer.apple.com/library/...d/10000011-SW1
1
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
07.07.2013, 23:25 15
Цитата Сообщение от noname_club Посмотреть сообщение
strong - обозначает строгое переназначение объекта, делая указатель на объект владельцем этого объекта
weak - в отличии от strong обозначает нестрогое соответствие и если объект был освобожден из памяти (из другого класса или потока), то значение установится в nil. Не поддерживается OS X v10.6 и iOS 4; используйте assign
copy - указывает на то, что для присваивания будет использована копия переданного объекта. Первоначальному объекту посылается сообщение release. Может быть использовано только для объектов, поддерживающих протокол NSCopying, например NSString.
assign - для задания нового значения используется оператор присваивания. Используется только для скалярных типов (NSInteger и CGRect) либо для объектов, которыми мы не владеем.
что то как то мудрено все
как написал Vorona можно почитать в офф документации там все понятно написано или вот тут
также исходя из всего этого:

strong = retain и вот что пишут apple: strong is the default. An object remains “alive” as long as there is a strong pointer to it.

assign = unsafe_unretained и опять же apple пишут: specifies a reference that does not keep the referenced object alive and is not set to nil when there are no strong references to the object. If the object it references is deallocated, the pointer is left dangling.

а weak это: specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
weak и assign похожи, но есть небольшая разница она описана выше.
1
Veyron
106 / 106 / 9
Регистрация: 02.06.2009
Сообщений: 578
08.07.2013, 16:27  [ТС] 16
Еще такой вопрос: как происходит работа с объектом в NSMutableArray addObject: ? В офф доке написано назначение метода, но не написали его поведение - он ритейнит объект, делает копию или просто добавляет указатель в контейнер?

Добавлено через 1 минуту
Судя по тому, что
Parameters
anObject
The object to add to the end of the array's content. This value must not be nil.
Явно не просто указатель. Тогда копирование или retain?
0
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
08.07.2013, 16:37 17
да он просто ретеинит объект, но тебе об этом заботиться не надо.
1
08.07.2013, 16:37
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.07.2013, 16:37

Есть ли утечка памяти в проекте? И как можно это перепроверять?
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace std; class MyArray...

Здесь есть какие нибудь ошибки ? и как здесь получается в ответе 6.25?
program r2; var b:real; begin b:=100; repeat b:=b/2; until b&lt;10; writeln...

HttpWebRequest, расход памяти непомерно больших объемов и , как следствие, утечка памяти
Добрый вечер. Мне была поставлена такая задача. Написать приложение, которая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru