Форум программистов, компьютерный форум CyberForum.ru

Программирование iOS/iPhone

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Veyron
106 / 106 / 4
Регистрация: 02.06.2009
Сообщений: 579
#1

Есть ли здесь утечка памяти? - Программирование iOS

06.07.2013, 13:24. Просмотров 1338. Ответов 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 или нет?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2013, 13:24
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Есть ли здесь утечка памяти? (Программирование iOS):

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

Есть ли утечка памяти? - C++
Пример добавления элемента в список. // Включение в список нового компонента void comp_in(dyn_list &l, char* n, char* v) { comp*...

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

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

Есть ли утечка памяти в проекте? И как можно это перепроверять? - C++
#include "stdafx.h" #include <iostream> using namespace std; class MyArray { int *ptrarray; //массив ...

Здесь есть какие нибудь ошибки ? и как здесь получается в ответе 6.25? - Turbo Pascal
program r2; var b:real; begin b:=100; repeat b:=b/2; until b<10; writeln (b:0:2); end. Здесь есть какие нибудь ошибки ?...

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

Добавлено через 2 минуты
Pro2005, и, насколько я понял и пробовал - release невыделенного объекта не вызывает утечки. У меня просто вылетала ошибка неверного обращения к памяти. Меня интересует утечка именно в смысле потери выделенного места (без его возврата в пул), которая скорее всего будет для response.
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
06.07.2013, 18:02 #5
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Veyron Посмотреть сообщение
Не подскажете, локальные переменные автоматически освобождаются при выходе из тела метода? Если нет - как быть с response?
для того что бы не было утечек в таких случаях посылается autorelease
а вообще вот тут все подробно написано
Veyron
106 / 106 / 4
Регистрация: 02.06.2009
Сообщений: 579
06.07.2013, 19:19  [ТС] #6
Xavier, и правда, статьи там очень хороши. Что ни говори - официальная документация всегда лучше всего :-)

Однако я не нашел ответ на один свой вопрос:
Objective-C
1
2
NSNumber *number = [[NSNumber alloc] init];
NSNumber *number_too = number;
Какой тогда будет счетчик ссылок на этот объект?
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 будет ошибка.
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
07.07.2013, 00:31 #8
получаем что :

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

поправьте если что неверно
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
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
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 не используется
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];
Veyron
106 / 106 / 4
Регистрация: 02.06.2009
Сообщений: 579
07.07.2013, 21:10  [ТС] #12
Xavier, а где еще можно почитать о спецификаторах в свойствах (assing, weak, retain, strong...) ?
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
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, во избежание коллизий с возможностью доступа к свойству из других потоков в сеттере строится код блокирующий переключение между потоками.
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,277
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
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 похожи, но есть небольшая разница она описана выше.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.07.2013, 23:25
Привет! Вот еще темы с ответами:

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

Вектор, утечка памяти, функция создания и выделение памяти - C (СИ)
Здравствуйте. Есть проблема. функция malloc выделяет память лишь в функции CreateVector(), и при выходе из нее указатель теряется. Или не...

.NET 3.x Утечка памяти - C# ASP.NET
Здравствуйте, всезнающие форумчане!!! Столкнулись с проблемой утечки оперативной памяти: Под серверный процесс w3wp.exe выделяется 1,4 Гб...

Утечка памяти - C++ Builder
Здравствуйте. Есть функция void fun(...) { TStringList *L = new TStringList(); ... ... delete L; }


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
07.07.2013, 23:25
Ответ Создать тему
Опции темы

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