Правильное управление памятью для метода Objective-C - PullRequest
0 голосов
/ 07 января 2011

Я программирую приложение для iPhone, и у меня возник вопрос об управлении памятью одним из моих методов.Я все еще немного новичок в управлении памятью вручную, поэтому извините, если этот вопрос кажется элементарным.

Ниже приведен метод, позволяющий цифровой клавиатуре размещать кнопки в метке на основе их тега,таким образом, мне не нужно создавать метод для каждой кнопки.Метод работает нормально, мне просто интересно, отвечаю ли я за освобождение любых переменных, которые я делаю в функции.

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

Вот метод:

К вашему сведению, переменная firstValue - это моя метка, это единственная переменная, не объявленная в методе.

-(IBAction)inputNumbersFromButtons:(id)sender {
    UIButton *placeHolderButton = [[UIButton alloc] init];
    placeHolderButton = sender;

    NSString *placeHolderString = [[NSString alloc] init];
    placeHolderString = [placeHolderString stringByAppendingString:firstValue.text];

    NSString *addThisNumber = [[NSString alloc] init];
    int i = placeHolderButton.tag;

    addThisNumber = [NSString stringWithFormat:@"%i", i];

    NSString *newLabelText = [[NSString alloc] init];
    newLabelText = [placeHolderString stringByAppendingString:addThisNumber];

    [firstValue setText:newLabelText];

    //[placeHolderButton release];
    //[placeHolderString release];
    //[addThisNumber release];
    //[newLabelText release];

}

Приложение отлично работает с последними четырьмя закомментированными строками, но мне кажется, что я должен выпустить эти переменные здесь.Если я ошибаюсь по этому поводу, я бы приветствовал краткое объяснение того, когда необходимо выпускать переменные, объявленные в функциях, а когда нет.Спасибо.

Ответы [ 4 ]

3 голосов
/ 07 января 2011

Да, вам нужно освободить их, но они нужны вам чуть дольше, чем за пределами вашей функции.

Решение называется autorelease. Просто замените release на autorelease, и объекты останутся, пока программа не вернется к циклу выполнения.

Когда программа возвращается туда, все заинтересованные в одном из объектов должны были отправить ему сообщение retain, поэтому объект не будет освобожден при освобождении NSAutoreleasePool.

edit на самом деле, глядя на ваш код, с ним гораздо больше проблем. Например. это:

UIButton *placeHolderButton = [[UIButton alloc] init];
placeHolderButton = sender;

не имеет смысла. Сначала вы выделяете объект, затем присваиваете (указатель) его переменной placeHolderButton. Это нормально.

Затем вы присваиваете sender этой же переменной. Ссылка на только что созданный объект теперь потеряна.

Не уверен, получу ли я то, что вы хотите, но это будет лучше:

-(IBAction)inputNumbersFromButtons:(id)sender {
    UIButton *placeHolderButton = sender; // this is still a little useless, but ok

    int i = placeHolderButton.tag;
    NSString *addThisNumber = [NSString stringWithFormat:@"%i", i];

    NSString *placeHolderString = firstValue.text;

    NSString *newLabelText = [placeHolderString stringByAppendingString:addThisNumber];

    [firstValue setText:newLabelText];
}

Нет ассигнований, поэтому релизы не нужны. Строки, возвращаемые этими функциями, уже добавлены в autoreleasepool, поэтому они будут освобождены автоматически (при необходимости).

0 голосов
/ 24 октября 2011

Мне кажется странным, что вы используете alloc / init для UIButton.

Я всегда использую фабричные методы, например,

UIButton* aButton = [UIButton buttonWithType:UIButtonTypeCustom];

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

Не может подтвердить это прямо сейчас, но похоже, что SDK кэширует экземпляры UIButton и выполняет некоторую оптимизацию за кулисами.Каждый раз, когда я пытался сохранить ивар UIButton, производительность снижалась (особенно, когда на экране много подвидов)

0 голосов
/ 07 января 2011

вам нужно выпустить что-либо, содержащее слово new, alloc / init или copy.

также вам не нужно выделять / инициализировать это:

UIButton *placeHolderButton = [[UIButton alloc] init];
placeHolderButton = sender;

другой способэто делается следующим образом:

UIButton *placeHolderButton = (UIButton *)sender;

в вашей версии, он выделяет экземпляр с счетом сохранения +1, но вы немедленно заменяете ссылку, поэтому нет возможности освободить память позже.

вы создаете много экземпляров с помощью alloc / init, а затем заменяете их ссылки автоматически выпущенными экземплярами.

вы можете использовать

    NSString *placeHolderString = [placeHolderString stringByAppendingString:firstValue.text];

вместо

 NSString *placeHolderString = [[NSString alloc] init];
placeHolderString = [placeHolderString stringByAppendingString:firstValue.text];

, который снова заменяет управляемый вручную экземпляр, созданный в первой строке, на автоматически выпущенный экземпляр во второй.

В действительности вы можете заменить каждый alloc / init в этом методе фабрики и не иметьиметь дело с памятью вообще в этом, поскольку они были бы автоматически выпущенными экземплярами.

-(IBAction)inputNumbersFromButtons:(id)sender {
    //cast sender as a UIButton to suppress compiler warning, and allow us to reference it as placeholder button
    UIButton *placeHolderButton = (UIButton *) sender;

    int i = placeHolderButton.tag;

    NSString *addThisNumber = [NSString stringWithFormat:@"%i", i];
    [firstValue setText:[firstValue.text stringByAppendingString:addThisNumber]];
}

Если вы посмотрите на документы класса для NSString, любой метод с + рядом с ним (т.е.*) string) - это метод класса, не используйте эти методы для ссылки после того, как вы вызвали для нее alloc / init.

0 голосов
/ 07 января 2011

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

Затем отпустите их в методе dealloc.

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

...