Вопросы управления памятью - PullRequest
0 голосов
/ 19 июля 2011

Я программирую в Objective-C уже пару недель, и я думаю, что пришло время больше думать об управлении моей памятью, и поэтому у меня есть пара сценариев, по которым я хотел бы получить разъяснения.

NSString *myString = @"Hello, World";

Если бы я был на следующей строке, сделайте

NSString *anotherString = myString;

Копируется ли это?или другая строка просто указатель на myString?если это просто указатель, как бы я сделал anotherString копией myString, которая имеет собственную память?

Что если бы я

[anotherString release];

Что на самом деле освобождается, просто anotherString или делаетmyString тоже исчезнет?

Тогда, если бы я должен был сделать

anotherString = nil;

Освобождает ли это память на самом деле и для использования, или же ей все еще выделяется пространство с пустой памятью?Очевидно, что указатель все еще может быть использован.Что это делает с myString?

Это действительно поможет мне лучше управлять памятью, а не просто [object release]; случайным образом и вызывать сбои.

Заранее ОГРОМНОЕ спасибокто бы ни ответил.

Ответы [ 3 ]

2 голосов
/ 19 июля 2011

Когда вы делаете:

NSString *myString = @"Hello, World";
NSString *anotherString = myString;

... вы создаете один экземпляр NSString и два указателя на него.Так что, чтобы ответить на ваши вопросы, нет, это не копируется.Да, anotherString - это просто указатель, как и myString, фактический экземпляр NSString отключен в области памяти по адресу, на который сейчас указывают оба указателя.

Чтобы создатькопию строки вы должны сделать:

NSString *anotherString = [myString copy];

Когда вы выполните:

[anotherString release];

Экземпляр NSString, на который указывает anotherString, освобождается.Ничего не происходит с anotherString.Он продолжает указывать на ваш теперь недействительный экземпляр объекта.Если myString указывал на тот же экземпляр, то да, это заставляет myString также «уходить».

И если вы делаете:

anotherString = nil;

...затем вы вызвали утечку памяти, потому что вы переназначили указатель, не отпуская то, на что он указывал.За исключением случаев, когда это не так, потому что @"Hello, World" является литеральным значением, которое загружается в стек и не сохраняется вашим кодом.

В любом случае, установка anotherString в nil не повлияет на вашу строку, он просто меняет то, на что указывает anotherString.Ваш фактический NSString экземпляр все еще отключен в памяти, совершенно не подозревая, что вы просто выбросили свою ссылку на него (возможное исключение: подсчет ссылок / сборщик мусора).

И да, вызов [object release]случайно вызовет сбои.Как правило, вам следует звонить на номер release только в том случае, если:

  1. Вы позвонили alloc и init... на него.
  2. Вы позвонили retain на него.
  3. Вы получили объект в результате вызова copy на каком-то другом объекте.

Обратите внимание, что это стек, поэтому, если вы alloc что-то, retain it,а затем copy это, вам нужно сделать 3 вызова на release, два для объекта, который вы alloc 'редактировали, и один для копии.

В качестве примечания вы можете найтипроще написать ваши объявления объектов, например:

NSString* myString = @"Hello, World";
NSString* anotherString = myString;

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

0 голосов
/ 19 июля 2011

NSString * anotherString = myString;

--- Это просто назначение указателя

--- Вы можете скопировать myString, используя [myString copy]

[anotherStringrelease];

--- Вы освобождаете корабль владельца другого String (пожалуйста, прочитайте о концепции сохранения счета)

anotherString = nil;

--- выпросто присвоение указателя ничему.

Я предлагаю. Пожалуйста, прочитайте больше о яблочных документах по управлению памятью ...

0 голосов
/ 19 июля 2011

Эта строка:

NSString *myString = @"Hello, World";

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

Если вы хотите скопировать строку в кучу (где вы можете управлять памятью), вы просто делаете это:

NSString *anotherString = [myString copy];

Тогда вы несете ответственность за освобождение этого объекта, когда закончите с ним.

[anotherString release];

Установка указателя на ноль просто очищает указатель, а не объект, на который он указывает. Это все еще в памяти.

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