управление памятью, должен ли в этом случае использоваться релиз? - PullRequest
1 голос
/ 13 декабря 2008

Учитывая следующий фрагмент кода внутри метода;

NSBezierPath * tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
            [tempPath retain];
            [path release];
            [self setPath:tempPath];

Я несу ответственность за выпуск tempPath или это будет сделано для меня?
setPath равен @synthesize d, поэтому я, вероятно, смогу также пропустить [path release]?

Я знаю, что лучший способ сделать это просто;

[path appendBezierPathWithOvalInRect:pathRect];

Но, будучи новичком в Objective C и Cocoa, я пытаюсь понять, как все складывается вместе.

--- ДОБАВЛЕННОЕ СОДЕРЖАНИЕ

Отсутствие [tempPath retain] приводит к сбою в объекте NSView, который использует пути.
Результат отладчика:

(gdb) po [0x145dc0 path]

Program received signal EXC_BAD_ACCESS, Could not access

память. Причина: KERN_PROTECTION_FAILURE по адресу: 0x00000021 0x93c56688 в objc_msgSend ()



КОНФЕССИЯ ВИН - моя ошибка. Надеюсь, кто-то еще получит что-то полезное от моей ошибки. Я использовал assign вместо retain в объявлении @property. Исправление заставило код работать должным образом.

СПАСИБО ЗА ПОМОЩЬ ПАРНИМ

Ответы [ 3 ]

3 голосов
/ 13 декабря 2008

Если path является переменной экземпляра, поддерживающей метод -setPath:, то нет, вам абсолютно не следует выпускать ее вне вашего -dealloc метода. Вам не нужно вручную сохранять ваш объект tempPath, так как вы используете аксессор для сохранения этого объекта. Ваши методы доступа, -setPath: в этом случае, методы -init и -dealloc должны быть единственными методами, где вы будете вызывать -retain и -release для переменных вашего экземпляра.

Ваш код работает так же хорошо, и с меньшей вероятностью утечки памяти:

NSBezierPath *tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
[self setPath:tempPath];

Так как метод -bezierPathWithOvalInRect: возвращает автоматически освобожденный объект и ваш метод доступа сохранит его, вам больше ничего не нужно делать с ним.

1 голос
/ 13 декабря 2008

Давайте посмотрим на это по-другому:

Если бы вы не использовали синтезированные средства доступа, вы бы написали их сами. В своих простейших формах они выглядели бы так:

- (NSBezierPath *) path {
    return path;
}

- (void)setPath:(NSBezierPath *)newPath {
    if (path == newPath) {
        // both objects have the same pointer so are the same.
        return;
    }

    [path release];
    path = [newPath retain];
}

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

self.path = [NSBezierPath bezierPathWithOvalInRect:pathRect];
1 голос
/ 13 декабря 2008

Вам не нужно освобождать tempPath.

Вы также можете сбросить [tempPath retain] и [path release]. Об этом заботятся, синтезируя метод набора.

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