Этот код Objective C утечка памяти? - PullRequest
2 голосов
/ 15 августа 2010

Меня беспокоит то, что я создаю два целых, но не выпускаю их. Было бы лучше сделать их NSIntegers?

-(void) flipCoin {

    int heads = [headsLabel.text intValue];
    int tails = [tailsLabel.text intValue];

    if (random() %2 ==1 )
    {
        heads++;
    }
    else {
        tails++;
    }

    headsLabel.text = [NSString stringWithFormat:@"%d", heads] ;
    tailsLabel.text = [NSString stringWithFormat:@"%d", tails];

}

Ответы [ 4 ]

7 голосов
/ 15 августа 2010

Как отмечает sha, локальные переменные размещаются в текущем кадре стека. Как только текущий вызов функции возвращается, стек «выталкивается», и память, занятая для текущего вызова, не освобождается, а просто освобождается, пока не будет перезаписана следующим вызовом, который помещается в эту часть стека.

Так почему же мы должны выпускать переменные следующим образом:

MyClass *myObject = [[MyClass alloc] init];

Ну, на самом деле вам не нужно беспокоиться о «myObject». Он в стеке, как и ваши целые, и будет очищен после завершения текущего вызова.

Что вам нужно беспокоиться, так это память, которую myObject - указатель - указывает на . Это где-то в куче. Построение объекта включает запрос времени выполнения для некоторого полупостоянного места, чтобы поместить это; этот процесс возвращает адрес памяти, который хранит ваш указатель.

alloc и release - это идиомы Objective-C, которые в значительной степени заменяют функции C malloc() и free(), но все они в конечном итоге просят компьютер выделить память в куче и всю эту память в конечном итоге должен быть возвращен через пул авто-релиза, сообщение release или вызов free().

2 голосов
/ 15 августа 2010

int - это то, что известно как примитивный тип.Это не указатель на объект Objective-C, поэтому вы не можете его освободить.Вы даже не можете отправить ему сообщение.

NSInteger также является примитивным типом в том смысле, что он является typedef для примитивного типа (обычно long).Так что вы тоже не можете выпустить это.

Что вам нужно выпустить?Вам нужно освободить любой объект, который вы получили, отправив new, alloc или метод, содержащий copy.Вам также необходимо освободить объекты, которые вы отправили, сохранить.Таким образом, все локальные переменные в следующем должны быть освобождены:

-(void) foo
{
    NSString* aString  = [[NSString alloc] init];
    NSString* aString2 = [aString copy];
    NSString* aString3 = [someOtherString retain];
    NSString* aString4 = [@"some string" copy];
}

Обратите внимание, что из-за подробностей реализации, вы на самом деле можете избежать освобождения aString4, но вам не нужно об этом беспокоиться.1009 *

2 голосов
/ 15 августа 2010

Все типы данных по умолчанию (int, char, BOOL и т. Д.) Автоматически управляются для вас и не могут (и не могут быть) освобождены (для всех целей и задач). NSInteger s ведут себя также, как и signed int s (или signed long s на 64-битных машинах).

Объекты, которые вы инициализируете, однако, такие как NSString или NSArray, обычно должны быть освобождены (если они не были автоматически освобождены, как NSString s внизу вашего кода). Если вы когда-нибудь позвоните по номеру -alloc и -init, вам придется позже отпустить это. Если вы когда-нибудь сомневаетесь в том, возвращает ли метод автоматически выпущенный объект, просто прочитайте документацию (он скажет вам).

Кроме того, если вы хотите прочитать об управлении памятью, есть множество замечательных источников, которые научат вас (Google - отличное место для старта!), И если вы когда-нибудь подумаете, что ваш код утечет памяти, запустите его через Инструменты, и вы сможете сказать ...

2 голосов
/ 15 августа 2010

Нет. Ваши переменные heads и tails являются локальными и хранятся в стеке. Это не приведет к утечке. Ваши два NSString назначения внизу созданы с помощью удобных конструкторов и будут автоматически освобождены для вас.

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